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,

Другие вопросы по тегам