繁体   English   中英

Java 8 flatmap,流式收集

[英]Java 8 flatmap , stream,collect

我有一种情况

class A {
    private B b;

    public B getB() {
        return b;
    }
}

还有另一个B类

class B {
    private List<C> c;

    public List<C> getListC() {
        return c;
    }
}

现在,类C包含两个实例变量

class C {
     private int id;
     private String name;

     public int getId() { 
         return id;
     }

     public String getName() {
         return name;
     }
}

现在我想使用Java 8实现以下目标

List<C> newListC = a.getB().getListC();
Map<Integer, String> map = new HashMap<>();

for(C c : newListC) {
  map.put(c.getId,c.getName());
}

我已经尝试了很多次,但是每次遇到不同的问题。 我的代码:

    Optional<A> a=Optional.of(new A());
    Map<Integer, String> map= a.map(A::getB)
                            .flatMap(b ->
                                    b.getListC()
                                            .stream()
                                            .collect(Collectors.toMap(
                                        C::getId,
                                        C::getName
                                                    )
                                            )
                            );

错误信息 :

Error:(164, 33) java: incompatible types: no instance(s) of type
variable(s) U,R,A,capture#1 of ?,T,K,U exist so that
java.util.Optional<U> conforms to
java.util.Map<java.lang.Integer,java.lang.String>

提前致谢

虽然我看到一些错字,但遇到了一些编译错误,但是

尝试:

    List<C> newListC= new A().getB().getListC();

    Map<Integer, String> stringMap = newListC.stream()
            .collect(Collectors
                    .toMap(C::getId, C::getName));

如果您已解决了编译问题,则它发出的结果应与map的非流版本相同。

您不能flatMap MapOptional ; 函数必须返回Optional 另一方面,由于该函数不返回Optional ,所以flatMap是不必要的,普通map可以做到:

Map<Integer, String> map = Optional.of(new A())
    .map(A::getB)
    .map(b -> b.getListC().stream().collect(Collectors.toMap(C::getId, C::getName)))
    .orElse(Collections.emptyMap());

但是由于new A()的结果不能为null(并且使用of代替ofNullable承认这一点),因此不需要在链的开头进行间接处理:

Map<Integer, String> map = Optional.ofNullable(new A().getB())
    .map(b -> b.getListC().stream().collect(Collectors.toMap(C::getId, C::getName)))
    .orElse(Collections.emptyMap());

但是请注意,仅处理getB结果的getB为空性,因为传递到下一个映射步骤的函数无条件调用getListC返回的列表上的stream() 但是无论如何在期望的List处返回null仍然是不好的编码风格。 您总是可以返回一个空列表来表示缺少值。

也许您的困惑源自基于Stream的替代解决方案:

Map<Integer, String> map = Stream.of(new A().getB())
    .filter(Objects::nonNull)
    .flatMap(b -> b.getListC().stream())
    .collect(Collectors.toMap(C::getId, C::getName));

在这里,创建了一个由最多一个元素组成的流,然后使用flatMap将其getListCgetListC返回的列表项中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM