所以我想创建一个Spring Boot
与 Spring Data JPA
项目使用 Kotlin
假设我有一个 Person
实体。我们可以这样说:
@Entity
public class Person {
private @GeneratedValue @Id Long id;
private String name;
@OneToMany
private List<Person> friends;
…
}
我将创建以下接口(interface)以便能够使用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());
}
}
}
现在,如果您想在 Kotlin 中执行此操作(IntelliJ 转换器不会生成有效代码)。我想你通常会这样做:
class MyService @Autowired constructor(val personRepository: PersonRepository) {
fun foo() {
val list = personRepository.findAllStream()
.use {{p -> p.friends.stream()}.map {f -> f.name}}
}
}
只有你不能这样做,因为没有#use
流上的方法,您无法调用 #stream()
来自List
。那么有什么办法可以做到这一点吗?
最佳答案
好吧,Kotlin 中对 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 新手,您必须注意到扩展是静态解析的:
Extensions do not actually modify classes they extend. By defining an extension, you do not insert new members into a class, but merely make new functions callable with the dot-notation on instances of this class.
查看更多http://kotlinlang.org/docs/reference/extensions.html#extensions-are-resolved-statically
关于spring - 如何使用 Spring Data JPA 方法在 Kotlin 的 try-with-resources block 中返回 Stream?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35542972/