Как использовать Spring Data JPA методы, возвращающие поток в блок try-with-resources в Котлине?

Поэтому я хочу создать Spring Boot с проектом Spring Data JPA с использованием Kotlin и позволяет сказать, что у меня есть объект Person . Давайте скажем так:

 @Entity public class Person { private @GeneratedValue @Id Long id; private String name; @OneToMany private List<Person> friends; … } 

Я бы создал следующий интерфейс, чтобы иметь возможность использовать Try-with-Resources и Stream<Person> .

 public interface PersonRepository extends Repository<Person, Long> { @Query("select p from Person p") Stream<Person> findAllStream(); } 

Поэтому, как правило, я выполняю это:

 @Service class MyService { @Autowired PersonRepository repository; List<String> foo() { try(Stream<Person> stream = repository.findAllStream()) { return stream.flatMap(p -> p.getFriends().stream()) .map(f -> f.getName()) .collect(Collectors.toList()); } } } 

Теперь, если вы хотите сделать это в Котлине (конвертер IntelliJ не производит действительный код). Я полагаю, вы обычно делаете что-то вроде:

 class MyService @Autowired constructor(val personRepository: PersonRepository) { fun foo() { val list = personRepository.findAllStream() .use {{p -> p.friends.stream()}.map {f -> f.name}} } } 

Только вы не можете это сделать, поскольку в #use нет метода #use и вы не можете вызвать #stream() из List . Так есть ли способ сделать это?

Ну, поддержка Java 8 еще не завершена в Котлине. Таким образом, вы можете просто объявить использование на вашей стороне, как это

 inline fun <A : AutoCloseable, R> A.use(block: (A) -> R): R { try { return block(this) } finally { close() } } 

Другая альтернатива – объявить ее непосредственно в Stream

 inline fun <T, R> Stream<T>.use(block: (Stream<T>) -> R): R { try { return block(this) } finally { close() } } 

UPD

Если вы новичок в Kotlin, вы должны заметить, что расширения разрешены статически:

Расширения фактически не изменяют классы, которые они расширяют. Определяя расширение, вы не вставляете новые члены в класс, а просто делаете новые функции вызываемыми с точечной нотацией на экземплярах этого класса.

Подробнее http://kotlinlang.org/docs/reference/extensions.html#extensions-are-resolved-static