Jam*_*eeh 16 java java-8 java-stream
我有一个Foo对象流.
class Foo {
private int variableCount;
public Foo(int vars) {
this.variableCount = vars;
}
public Integer getVariableCount() {
return variableCount;
}
}
Run Code Online (Sandbox Code Playgroud)
我想要一个列表,Foo它们都具有最低的variableCount.
例如
new Foo(3), new Foo(3), new Foo(2), new Foo(1), new Foo(1)
Run Code Online (Sandbox Code Playgroud)
我只希望流返回最后2 Foo秒
我试过用分组进行收集
.collect(Collectors.groupingBy((Foo foo) -> {
return foo.getVariableCount();
})
Run Code Online (Sandbox Code Playgroud)
这会返回一个Map<Integer, List<Foo>>,我不知道如何将其转换为我想要的.
提前致谢
lex*_*ore 14
您可以使用有序地图进行分组,然后只获取第一个条目.一些事情:
Collectors.groupingBy(
Foo::getVariableCount,
TreeMap::new,
Collectors.toList())
.firstEntry()
.getValue()
Run Code Online (Sandbox Code Playgroud)
rge*_*man 10
这是一个解决方案:
Foos都具有相同的变量计数,在这种情况下,此解决方案将存储所有项目,如其他解决方案.但在实践中,由于具有不同的,不同的值和更高的基数,列表中的项目数量可能会低得多.编辑
我根据评论中的建议改进了我的解决方案.
我实现了一个累加器对象,它Collector为此提供了函数.
/**
* Accumulator object to hold the current min
* and the list of Foos that are the min.
*/
class Accumulator {
Integer min;
List<Foo> foos;
Accumulator() {
min = Integer.MAX_VALUE;
foos = new ArrayList<>();
}
void accumulate(Foo f) {
if (f.getVariableCount() != null) {
if (f.getVariableCount() < min) {
min = f.getVariableCount();
foos.clear();
foos.add(f);
} else if (f.getVariableCount() == min) {
foos.add(f);
}
}
}
Accumulator combine(Accumulator other) {
if (min < other.min) {
return this;
}
else if (min > other.min) {
return other;
}
else {
foos.addAll(other.foos);
return this;
}
}
List<Foo> getFoos() { return foos; }
}
Run Code Online (Sandbox Code Playgroud)
然后我们要做的就是collect引用累加器的函数方法.
List<Foo> mins = foos.stream().collect(Collector.of(
Accumulator::new,
Accumulator::accumulate,
Accumulator::combine,
Accumulator::getFoos
)
);
Run Code Online (Sandbox Code Playgroud)
测试用
List<Foo> foos = Arrays.asList(new Foo(3), new Foo(3), new Foo(2), new Foo(1), new Foo(1), new Foo(4));
Run Code Online (Sandbox Code Playgroud)
输出是(有一个合适的toString定义Foo):
[Foo{1}, Foo{1}]
Run Code Online (Sandbox Code Playgroud)
如果你可以流式传输(迭代)两次:
private static List<Foo> mins(List<Foo> foos) {
return foos.stream()
.map(Foo::getVariableCount)
.min(Comparator.naturalOrder())
.map(x -> foos.stream()
.filter(y -> y.getVariableCount() == x)
.collect(Collectors.toList()))
.orElse(Collections.emptyList());
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2011 次 |
| 最近记录: |