以下是以下解决方案:
- 仅流式传输列表一次。
- 不构建包含所有输入项的映射或其他结构(除非变量计数都相同),仅保留当前最小值的映射或其他结构。
- 是 O(n) 时间,O(n) 空间。完全有可能所有 s 都具有相同的变量计数,在这种情况下,此解决方案将像其他解决方案一样存储所有项目。但实际上,由于值不同且基数较高,列表中的项目数可能会低得多。
Foo
编辑
我根据评论中的建议改进了我的解决方案。
我实现了一个累加器对象,它为此提供函数。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; }
}
那么我们所要做的就是,引用累加器的方法来实现其函数。collect
List<Foo> mins = foos.stream().collect(Collector.of(
Accumulator::new,
Accumulator::accumulate,
Accumulator::combine,
Accumulator::getFoos
)
);
测试
List<Foo> foos = Arrays.asList(new Foo(3), new Foo(3), new Foo(2), new Foo(1), new Foo(1), new Foo(4));
输出是(在 上定义了合适的):toString
Foo
[Foo{1}, Foo{1}]