【问题标题】:JAVA8 Optional and LambdasJAVA8 可选和 Lambda
【发布时间】:2021-08-13 14:42:37
【问题描述】:

假设我有这个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 值(如果exixsts)并映射子关系以获得C 类的所有id。我尝试过这样的事情:

  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 中,我尝试了几种方法,但都没有成功。

反正我不明白为什么不能连续使用两个maplike

 .map(x -> x.getC())
 .flatMap(List::stream)
 .map(y -> y.getId())

中间不使用flatMap(List::stream)...map 不会返回R 类型的新Stream(在这种情况下为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);

我想适应我的情况,但没有运气。

【问题讨论】:

  • 1) 根本不清楚为什么要创建这个多余的 Optional,然后 2) 不清楚“我想在我的 lambda 中放入 a.get().getB()”应该是什么意思。哪个拉姆达?当你已经有了可以正常工作的代码时,为什么还要把那个表达式放在里面呢? 3) 见What's the difference between map() and flatMap() methods in Java 8? 或者简而言之,你能在List&lt;C&gt; 上调用getId() 吗?或者您是否需要一个构造来告诉您要为每个元素执行此操作(例如通过流式传输)?
  • 当您调用一个有意返回可选的方法时,即因为它可能返回一个空的可选,您不应该对其执行无条件调用get
  • 你必须使用 flatMap 因为你有一个列表列表(每个 B 都有一个 C 列表并且你有很多 B)。

标签: java lambda java-8 optional flatmap


【解决方案1】:

及更新版本,您可以致电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());

如果你卡在,你需要映射到Stream(或返回空的)并继续链接:

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&lt;A&gt; a = Optional.of(a) 无效,因为 a 已定义。

【讨论】:

  • 非常感谢,这是我一直在寻找的,Optional&lt;A&gt; a Optional.of(a) 是一个打字错误(或最多是伪代码!)。非常感谢。
  • 不客气。 :) 下次请尽量避免将此类伪代码与真实代码混合,因为这可能会导致其他人专注于该错字而不是发布有用的答案。
猜你喜欢
  • 2014-10-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多