책정리/Kotlin in Action

[Kotlin in Action] 컬렉션과 배열, (MutableCollection, 자바와의 관계)

뽀글보리 2021. 10. 21. 20:05
반응형

6.3 컬렉션과 배열

  • 코틀린의 컬렉션 지원과 자바와 코틀린 컬렉션 간의 관계

6.3.1 널 가능성과 컬렉션

List<Int?>와 List<Int>?의 차이

  • (1) : 리스트 자체는 널이 아니다. 리스트에 들어있는 각 원소는 널이 될 수 있다.
  • (2) : 리스트 자체가 널이 될 수 있다. 리스트에 들어있는 원소는 널이 될 수 없다.

널 값 거러내기

// List<Int?> -> List<Int> 
val validNumbers = numbers.filterNotNull()

6.3.2 읽기 전용과 변경 가능한 컬렉션

  • kotlin.collections.Collection : 컬렉션 안의 데이터 접근
  • kotlin.collections.MutableCollection : Collection 인터페이스 확장 & add, remove, clear 메소드 제공
fun <T> copyElements(source: Collection<T>, target: MutabeleCollection<T>){ 
	for (item in source) { 
    	target.add(item) 
    } 
}
  • target에 읽기 전용 컬렉션을 넘길 경우 컴파일 오류가 난다.

읽기 전용 컬렉션이 항상 thread safe 하지 않다.

val a: MutableList<String> = mutableListOf("a", "b") 
val list: List<String> = a 

val mutableList: MutableList<String> = a
  • list는 변경불가능하지만, 병렬 실행할 경우 다른 컬렉션(mutableList)이 그 컬렉션의 내용을 변경하는 상황이 생길 수도 있다.

6.3.3 코틀린 컬렉션과 자바

  • 모든 코틀린 컬렉션은 그에 상응하는 자바 컬렉션 인터페이스의 인스턴스이다.
  • 코틀린은 자바의 ArrayList가 코틀린의 MutableList 인터페이스를 상속한 것처럼 취급한다.

컬렉션 생성 함수

  • 코틀린에서 읽기 전용 Collection으로 선언되었더라도 자바에서는 변경할 수 있다. → 컴파일러가 이를 막을 수 없다. → 책임은 여러분에게 있다.

6.3.4 컬렉션을 플랫폼 타입으로 다루기

  • 자바 메소드 구현을 오버라이드하려는 경우, 자바쪽에서 선언한 컬렉션 타입의 변수를 코틀린에서는 플랫폼 타입으로 본다.
  • 어떤 맥락에서 사용되는 정확히 알고 결정내리자.
  1. 컬렉션이 널이 될 수 있는가?
  2. 컬렉션의 원소가 널이 될 수 있는가?
  3. 오버라이드하는 메소드가 컬렉션을 변경할 수 있는가?
interface FIleContentProcessor { 
	void processContents(File path, bytep[] binaryContents, List<String> textContents); 
}
  1. 이진파일을 텍스트로 표현할 수 없는 경우가 있으므로 리스트는 널이 될 수 있다.
  2. 파일의 각 줄이 널이 될 수 없다.
  3. 파일 내용을 바꿀 필요 없으므로 읽기 전용이다.
class FileIndexer: FileContentProcessor { 
	override fun processContents(
    		path: File, 
            binaryContents: ByteArray?, 
            textContents: List<String>?) { 
     	// ... 
    } 
}

6.3.5 객체의 배열과 원시 타입의 배열

코틀린에서 배열을 만드는 방법

  • arrayOf 함수에 원소를 넘긴다.
  • arrayOfNulls로 정수 값을 넘긴다.
  • Array 생성자 + 람다 식을 사용한다.
val a = arrayOf("a", "b", "c") 
val b : Array<String?> = arrayOfNulls(3) 
val c = Array(26){ i -> ('a'+i).toString() }

코틀린에서 배열 변환이 필요한 경우

  • 배열을 인자로 받는 자바 함수 호출
  • vararg 파라미터를 받는 코틀린 함수를 호출
val strings = listOf("a", "b", "c") 
println("%s/%s/%s".format(*strings.toTypedArray()))

코틀린에서 원시 타입의 배열 만드는 방법

  • size 인자를 받아서 0으로 초기화된 배열 반환
  • intArrayOf 등의 팩토리 함수를 사용한다
  • 람다를 받는 생성자를 사용한다.
val fizeZeros = IntArray(5) 
val fiveZerosToo = intArrayOf(0,0,0,0,0) 
val squares = IntArray(5) { i->(i+1)*(i+1) }

forEachIndexed 함수 사용하기

fun main(args: Array<String>) {
	args.forEachIndexed { index, element -> println("$index is $element") } 
}
반응형