Java 8流 - 在flatmap

时间:2017-01-20 11:35:02

标签: java java-8 java-stream

我目前有以下代码。

方法 - parseGreeting()

    public GetGreetingNmsObjects parseGreeting(String greetingType, GetGreetingNmsResponse xmlFromNms) {

    GetGreetingNmsObjects objectFound = null;
    List<GetGreetingNmsObjects> objList = xmlFromNms.getObject();
    for (GetGreetingNmsObjects obj : objList) {

        List<Attribute> attrs = obj.getAttributes();
        Optional<Boolean> found = attrs.stream()
                                 .filter(a -> a.name.equals(GREETING_TYPE))
                                 .map(a -> a.value.equals(greetingType))
                                 .findAny();

        if(found.get()) {
            objectFound = obj;
            break;
        }

    return objectFound;
}

GetGreetingNmsObjects .java

public class GetGreetingNmsObjects {
    List<Attribute> attributeList;

    public List<Attribute> getAttributes() {
        return attributeList;
    } 
}

在上面的方法中,有没有办法避免for循环和if语句并使用流本身处理?

我尝试使用&#39; flatmap&#39;并获取&#39; attributesList&#39;的流但是一旦找到匹配项,我就无法参考“GetGreetingNmsObjects&#39;对象

GetGreetingNmsObjects objectFound = objList.stream()
                                   .flatMap(grt -> grt.getAttributes())
                                   .filter(a -> a.name.equals(GREETING_TYPE))
                                   .map(a -> a.value.equals(greetingType))
                                   ????

1 个答案:

答案 0 :(得分:11)

您的原始代码包含逻辑错误:

Optional<Boolean> found = …
                         .map(a -> a.value.equals(greetingType))
                         .findAny();

这将返回任意比较的结果,在顺序上下文中,它可能是第一个元素的结果。

我很确定你真的想知道是否有任何匹配元素,因此应该使用

boolean found = …
               .anyMatch(a -> a.value.equals(greetingType));

这可以简单地用作谓词来查找具有匹配元素的第一个元素:

return xmlFromNms.getObject().stream()
    .filter(obj -> obj.getAttributes().stream()
                      .filter(  a -> a.name.equals(GREETING_TYPE))
                      .anyMatch(a -> a.value.equals(greetingType)))
    .findFirst().orElse(null);