Java 8流优先过滤

时间:2018-10-17 10:47:28

标签: java java-8 java-stream

我的代码如下:

for (SomeObject object : objects) {
    if (object.getSomething() == Something.SomethingHighPriority) {
        return object;
    }
}

for (SomeObject object : objects) {
    if (object.getSomething() == Something.SomethingLowPriority) {
        return object;
    }
}

它用于通过某种条件获取集合中的第一个元素。同样,优先级很重要。我首先需要寻找一个元素,即使它不存在,也要寻找第二个元素。

我想使用Stream API重写它,但我知道流仅使用一次。 现在,我以这种方式重写了它,但它似乎比以前更加丑陋。

Optional<SomeObject> object = 
    objects.stream()
           .filter(object -> object.getSomething() == Something.SomethingHighPriority)
           .findFirst();

if (object.isPresent()) {
    return object.get();
}

object = objects.stream()
                .filter(object -> object.getSomething() == Something.SomethingLowPriority)
                .findFirst();

// No other use cases
return object.orElse(null);

是否可以减少样板?

3 个答案:

答案 0 :(得分:6)

您可以链接两个管道:

return objects.stream()
              .filter(object -> object.getSomething() == Something.SomethingHighPriority)
              .findFirst()
              .orElseGet(() -> objects.stream()
                                      .filter(object -> object.getSomething() == Something.SomethingLowPriority)
                                      .findFirst()
                                      .orElse(null));

另一种方法是按Stream降序对object.getSomething()进行排序,然后返回第一个元素(如果它具有两个必需值之一),但这将花费{{1} },效率较低。

答案 1 :(得分:1)

我认为您的代码还可以,对一个集合进行两次迭代不是一个坏方法。

但是,如果您只想通过一次,则可以收集到Map

Map<Something.Priority, Something> map = objects.stream()
    .filter(o -> o.getSomething() == Something.SomethingHighPriority
              || o.getSomething() == Something.SomethingLowPriority)
    .collect(Collectors.toMap(
                SomeObject::getSomething,
                Function.identity(),
                (oldObject, newObject) -> oldObject));

SomeObject highPriority = map.get(Something.SomethingHighPriority);

return highPriority == null ? map.get(Something.SomethingLowPriority) : highPriority;

答案 2 :(得分:0)

不确定SomethingHighPriority对您意味着什么,但是您可以尝试使用Comparator。首先为高和低创建两个谓词。使用或运算符将它们添加到过滤器中,因为您需要进行比较并获得最大值。

    Predicate<SomeObject> somethingHighPriority= e -> e.getSomething() == Something.SomethingHighPriority;
    Predicate<SomeObject> somethingLowPriority= e -> e.getSomething() == Something.SomethingLowPriority;
    Optional<SomeObject> first = objects.stream()
            .filter(somethingHighPriority.or(somethingLowPriority)) 
            .max(Comparator.comparing(objects::getSomething()));

    if (first.isPresent()) {
        return first.get();
    }
    return null;

最大值将处理优先级