我有一些物品。我需要从Set中获取两个min对象。
我的示例如下:
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class Example {
public static void main( String[] args ) {
SomeObject obj1 = new SomeObject(1);
SomeObject obj2 = new SomeObject(2);
SomeObject obj3 = new SomeObject(3);
Set<SomeObject> set = Stream.of(obj1,obj2,obj3)
.collect(Collectors.toSet());
SomeObject minObject= set.stream()
.min(Comparator.comparingInt(object->object.getValue()))
.get();
System.out.println(minObject);
}
}
class SomeObject{
private int value;
SomeObject(int value){
this.value=value;
}
public int getValue() {
return value;
}
@Override
public String toString() {
return this.value+"";
}
}
在我的示例中,我可以基于value属性从此Set中获取min对象。
因此,我需要使用java流操作来获取两个min值。
遮阳篷应该很快,因为在我的真实程序中,我多次调用此方法,并且集合很大。
答案 0 :(得分:5)
您可以获取第二个最小值,如下所示:
set.stream()
.filter(s -> s.getValue() != minObject.getValue())
.min(Comparator.comparingInt(object -> object.getValue()))
.get();
filter
忽略先前的最小值。min
或者您可以同时获得两者:
Stream<SomeObject> twoMinValues = set.stream()
.sorted(Comparator.comparingInt(object -> object.getValue()))
.limit(2);
遮阳篷应该很快,因为在我的真实程序中,我称之为 方法很多次,我的集合很大。
关于需要“快速”程序,我建议您首先尝试使用典型的命令式方法来解决当前的问题,因为在大多数情况下,它们比使用流更快。
如果并没有更好,那么仅当您知道可以利用并行性时,才“考虑”使用并行流。
答案 1 :(得分:2)
您可以将Set<E>
传递到NavigableSet<E>
的实例,然后可以轮询其中的前两个(最低)元素:
final NavigableSet<SomeObject> navigableSet = new TreeSet<>(Comparator.comparingInt(SomeObject::getValue));
navigableSet.addAll(set);
final SomeObject firstMin = navigableSet.pollFirst();
final SomeObject secondMin = navigableSet.pollFirst();
答案 2 :(得分:0)
通过流一次完成此操作的一种方法是编写一个自定义收集器:
class MinCollector implements Consumer<SomeObject> {
private TreeSet<SomeObject> minObjects =
new TreeSet<>(Comparator.comparingInt(o -> o.getValue()));
public TreeSet<SomeObject> getMinObjects() {
return minObjects;
}
@Override
public void accept(SomeObject object) {
minObjects.add(object);
if(minObjects.size() > 2 ) {
minObjects.remove(minObjects.last());
}
}
public void combine(MinCollector collector) {
for( SomeObject object : collector.minObjects ) {
accept( object );
}
}
}
// ...
TreeSet<SomeObject> minObjects = set
.stream()
.collect(MinCollector::new, MinCollector::accept, MinCollector::combine)
.getMinObjects();