我的代码如下:
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);
是否可以减少样板?
答案 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;
最大值将处理优先级