JAVA8 可选和 Lambda
JAVA8 Optional and Lambdas
假设我有这个 class
模型层次结构:
public class A {
private Integer id;
private List<B> b;
}
并且:
public class B {
private Integer id;
private List<C> c;
}
最后:
public class C {
private Integer id;
}
还有一个简单的 Service
:
@Service
public class doSome {
public void test() {
Optional<A> a = Optional.of(a) // Suppose a is an instance with full hierarchy contains values
/** *1 **/ // what I want to do
}
}
现在我想在 *1
位置做的是使用 lambda 提取 Optional
值(如果存在)并映射子关系以获得所有 id
C
class。我试过这样的事情:
public void test() {
Optional<A> a = Optional.of(a);
List<Integer> temp = a.get().getB()
.stream()
.map(x -> x.getC())
.flatMap(List::stream)
.map(y -> y.getId())
.collect(Collectors.toList()); // works
}
现在我想把 a.get().getB()
放入我的 lambda 中,我尝试了几种方法但没有成功。
反正我不明白为什么我不能连续使用两个map
like
.map(x -> x.getC())
.flatMap(List::stream)
.map(y -> y.getId())
没有在中间使用 flatMap(List::stream)
...map
不会 return 类型 R 的新 Stream
(class C 在这个案例)?为什么我又要Stream
呢?我哪里错了?
---------------------更新-----------------
这只是一个例子,很明显这里的 Optional
是没有用的,但在实际情况下可以通过 findById()
JPA 查询来实现。
Holger 出于这个原因,我会把所有内容都放在代码的一部分中,做一些类似的事情:
public <T> T findSome(Integer id) {
Optional<T> opt = repository.findById(id);
return opt.map(opt -> opt).orElse(null);
}
我在这里阅读了一些解决方案,如下所示:
Optional.ofNullable(MyObject.getPeople())
.map(people -> people
.stream()
.filter(person -> person.getName().equals("test1"))
.findFirst()
.map(person -> person.getId()))
.orElse(null);
我想适应我的情况,但运气不好。
从 java-9 开始,您可以调用 Optional#stream
:
List<Integer> temp = a.map(A::getB)
.stream()
.flatMap(Collection::stream)
.map(B::getC)
.flatMap(Collection::stream)
.map(C::getId)
.collect(Collectors.toList());
如果您遇到 java-8,您需要映射到 Stream
(或 return 空的)并继续链接:
List<Integer> temp = a.map(A::getB)
.map(Collection::stream)
.orElse(Stream.empty())
.map(B::getC)
.flatMap(Collection::stream)
.map(C::getId)
.collect(Collectors.toList());
注意: Optional<A> a = Optional.of(a)
无效,因为 a
已经定义。
假设我有这个 class
模型层次结构:
public class A {
private Integer id;
private List<B> b;
}
并且:
public class B {
private Integer id;
private List<C> c;
}
最后:
public class C {
private Integer id;
}
还有一个简单的 Service
:
@Service
public class doSome {
public void test() {
Optional<A> a = Optional.of(a) // Suppose a is an instance with full hierarchy contains values
/** *1 **/ // what I want to do
}
}
现在我想在 *1
位置做的是使用 lambda 提取 Optional
值(如果存在)并映射子关系以获得所有 id
C
class。我试过这样的事情:
public void test() {
Optional<A> a = Optional.of(a);
List<Integer> temp = a.get().getB()
.stream()
.map(x -> x.getC())
.flatMap(List::stream)
.map(y -> y.getId())
.collect(Collectors.toList()); // works
}
现在我想把 a.get().getB()
放入我的 lambda 中,我尝试了几种方法但没有成功。
反正我不明白为什么我不能连续使用两个map
like
.map(x -> x.getC())
.flatMap(List::stream)
.map(y -> y.getId())
没有在中间使用 flatMap(List::stream)
...map
不会 return 类型 R 的新 Stream
(class C 在这个案例)?为什么我又要Stream
呢?我哪里错了?
---------------------更新-----------------
这只是一个例子,很明显这里的 Optional
是没有用的,但在实际情况下可以通过 findById()
JPA 查询来实现。
Holger 出于这个原因,我会把所有内容都放在代码的一部分中,做一些类似的事情:
public <T> T findSome(Integer id) {
Optional<T> opt = repository.findById(id);
return opt.map(opt -> opt).orElse(null);
}
我在这里阅读了一些解决方案,如下所示:
Optional.ofNullable(MyObject.getPeople())
.map(people -> people
.stream()
.filter(person -> person.getName().equals("test1"))
.findFirst()
.map(person -> person.getId()))
.orElse(null);
我想适应我的情况,但运气不好。
从 java-9 开始,您可以调用 Optional#stream
:
List<Integer> temp = a.map(A::getB)
.stream()
.flatMap(Collection::stream)
.map(B::getC)
.flatMap(Collection::stream)
.map(C::getId)
.collect(Collectors.toList());
如果您遇到 java-8,您需要映射到 Stream
(或 return 空的)并继续链接:
List<Integer> temp = a.map(A::getB)
.map(Collection::stream)
.orElse(Stream.empty())
.map(B::getC)
.flatMap(Collection::stream)
.map(C::getId)
.collect(Collectors.toList());
注意: Optional<A> a = Optional.of(a)
无效,因为 a
已经定义。