Kotlin, нацеленный на взаимодействие с Java: идиоматический тип для отложенной коллекции?
При нацеливании на взаимодействие с Java, какой тип следует использовать для отложенной коллекции?
Sequence<T>
имеет смысл для вызывающих Kotlin из-за того, что функции расширения для него по умолчанию являются ленивыми, но заставляет вызывающие Java иметь дело с типом stdlib Kotlin и преобразовывать итератор последовательности вручную (последовательность не расширяется итеративно!)Iterable<T>
имеет смысл для вызывающих Java-программ из-за неявного использования циклов for, но из-за не ленивых функций расширения ничего не подозревающие вызывающие Kotlin могут случайно отбросить леньStream<T>
оптимален как для Java, так и для Kotlin, но может иметь дополнительные издержки и является Java 8+ (Kotlin предназначается для 6+)
1 ответ
Решение
Вы можете сделать всех счастливыми, внедрив все три. например:
data class User(val name: String)
fun userSequence(): Sequence<User> = TODO()
fun usersLazily(): Iterable<User> = userSequence().asIterable()
fun userStream(): Stream<User> = userSequence().asStream()
Не используя простое имя, как users
для любой из этих функций вы заставляете вызывающего думать немного больше о том, что они действительно хотят:
- Пользователи Kotlin будут использовать
userSequence
, - Java 1.6 и 1.7 пользователи будут использовать
usersLazily
, - Пользователи Java 1.8 будут использовать
userStream
,
userStream
должен быть определен в отдельном JAR, добавляя поддержку JDK 1.8 к вашему JAR 1.6 / 1.7 (аналогично тому, как org.jetbrains.kotlin:kotlin-stdlib-jre8
делает для org.jetbrains.kotlin:kotlin-stdlib
).
С учетом сказанного, я бы спросил, нужно ли вам поддерживать Java 1.6 или 1.7. Если вы обнаружите, что нет, то можете поставить userSequence
а также userStream
в тот же JAR и даже не определить usersLazily
,