ThreadLocalRandom에 대한 설명은 API문서를 찾아보시면 좋을 것 같습니다.
https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ThreadLocalRandom.html
Thread.current()대한 설명입니다.
Returns the current thread's ThreadLocalRandom.
현재 쓰레드에 대한 ThreadLocalRandom을 리턴한다. 즉, 현재 쓰레드에서 실행되는 인스턴스를 리턴하는 걸로 보이네요.
1. ints 메소드의 첫번째와 두번째 파라미터는 랜덤숫자를 생성하는 범위라고 보시면 됩니다. 예를들어 ints(20, 0, 10)이라고 하면 0부터 10사이의 정수(0 ~ 9)가 20개 생성되는 거죠.
2. Sequence는 Kotlin에서 Java의 stream처럼 빠른 연산을 위해 도입된 개념입니다. 이외에도 observable이 가능한 특성이 있기도 한데, 일단 collection을 사용할 때 성능향상을 위해 사용한다고 보시면 됩니다. 동작원리는 Kotlin 사이트에서 자세하게 읽어보세요. https://kotlinlang.org/docs/sequences.html 페이지 중간 쯤에 다이어그램이 있을 겁니다. 그 부분을 보세요. 간략하게 요약하면 List.filter().map().filter()이런 식으로 Collection의 functional(함수형) 연산이 여러개 들어갈 때 일반적인 방식은 filter 의 결과를map연산을 하고 이 결과를 다시 filter를 하는 순차적 연산이라면 sequqnce를 사용하게 되면 첫번째 아이템에 대해 filter.map.filter를 처리하고 다음아이템으로 넘어갑니다. 이때 filter가 걸리지 않는 아이템은 map이 호출되지 않게 됩나다.
3. 맵의 함수 정의는 아래와 같습니다.
public inline fun <T, R> Iterable<T>.map(transform: (T) -> R): List<R> {
return mapTo(ArrayList<R>(collectionSizeOrDefault(10)), transform)
}
https://github.com/JetBrains/kotlin/blob/d8b0dbe71bbeb84ba0fbdac87801c8c6f4eed4c9/libraries/stdlib/common/src/generated/_Collections.kt#L1548
map은 extension function(확장함수?)로 List<T>의 루프를 돌면서 T타입인 아이템을 R타입으로 변환하여 List<R> 을 반환하는 겁니다. 잘 보시면 transform 파라미터는 함수타입니다. 파라미터로 함수타입을 넘기고자 할때 ::연산자를 사용해서 함수타입을 넘길 수 있습니다.
아래의 둘은 같습니다. 함수포인터를 사용하느냐 아느냐의 차입니다.
map(charPool::get)
map{ index -> charPool.get(index) }
이걸 루프를 포함해서 작성하면, 아래와 같이 동작하게 됩니다.
val result = arrayListOf<Char>()
val indexes = ThreadLocalRandom().current.ints(20, 0, charPool.size)
for (index: Int in indexes) {
result.add(charPool.get(index))
}
적절하게 쓰면 좋지만 남발하면 좋지 않습니다. map은 코틀린 뿐만 아니라 모던한 랭귀지라면 다들 지원하는 함수형 오퍼레이터입니다.
map은 콜렉션의 아이템을 바꾸는 함수 중의 하나입니다. transformation 오퍼레이션은 자주 사용되고 다른 랭귀지에도 같은 기능들이 있으므로 잘 알아두시는게 좋습니다. filter, map, reduce정도는 잘 사용하실 수 있도록....
transformation에 대한 자세한 내용은 아래 링크를 읽어보세요.
https://kotlinlang.org/docs/collection-transformations.html
그리고 위의 코드를 코틀린의 extension function을 사용해서 다시 작성하면, 아래와 같이 할 수 있습니다.
val charPool = ...
charPool.shuffled().take(20)
// or
('a'..'z')
.plus('A'..'Z')
.plus('0'..'9')
.shuffled()
.take(20)
charPool을 섞어서 앞의 20개만 가져가는 코드입니다. 위의 예와 똑같이 동작할 겁니다. 역시나 간략해 보여서 좋긴하지만 너무 남발하면 곤란하겠죠.