我有结构
interface Foo{
List<Bar> getBars();
}
interface Bar{
List<Number> getValues();
}
并列出List<Foo> foos
我想要的是创建看起来或多或少像这样的 map ,排除 foo 没有 bar 或 bar 没有值的条目。
{
fooid :{
barId : bar
}
}
显然我的第一个想法是做
foos.stream().filter(f->!f.getBars().isEmpty())
.collect( Collectors.toMap(
f->f.id(),
f->f.getBars().stream().filter(b->!b.getValues().isEmpty())
.collect(Collectors.toMap( b->b.id(),b->b.getValues()
))));
问题是我正在调用方法 getValues
两次而且这是昂贵的方法,
处理此类调用的最佳实践是什么?
最佳答案
我认为这就是您正在寻找的:
private static void doMap(List<Foo> foos) {
foos.stream()
.filter(foo -> !foo.getBars()
.isEmpty())
.map(foo -> new SimpleEntry<>(foo.getId(), foo.getBars()
.stream()
.map(bar -> new SimpleEntry<>(bar.getId(), bar.getValues()))
.filter(entry -> !entry.getValue()
.isEmpty())
.collect(entriesToMapCollector())))
.filter(entry -> !entry.getValue().isEmpty())
.collect(entriesToMapCollector());
}
private static <K, V> Collector<Entry<K, V>, ?, Map<K, V>> entriesToMapCollector() {
return Collectors.toMap(Entry::getKey, Entry::getValue);
}
(出于可读性、可维护性和一切能力的考虑,我强烈提倡采用更命令式的方法 - 请不要在生产代码中这样做)
关于java - 在添加到 map 之前如何过滤收集器中方法调用的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55498481/