我有一段代码,它根据传入的一组字符串标识符从对象列表中过滤,并返回字符串id和对象的映射。类似于以下几点:
class Foo {
String id;
String getId() {return id};
};
// Get map of id --> Foo objects whose string are in fooStr
Map<String,Foo> filterMethod (Set<String> fooStr) {
List<Foo> fDefs; // list of Foo objects
Map<String,Foo> fObjMap = new HashMap<String, Foo>(); // map of String to Foo objects
for (Foo f : fDefs) {
if (fooStr.contains(f.getId()))
fObjMap.put(f.getId(),f);
}
return (fObjMap);
}是否有更好的Java8方法来使用过滤器或映射来完成此操作?我想不出答案,试着在堆栈溢出上搜索,但是找不到任何提示,所以我把它作为一个问题发布。
任何帮助都是非常感谢的。~灰
发布于 2018-07-07 02:26:14
只需使用与上述谓词相同的filter操作符,然后使用toMap收集器来构建映射。还请注意,您的迭代解决方案排除了任何关键冲突的可能性,因此,我也忽略了这一点。
Map<String, Foo> idToFooMap = fDefs.stream()
.filter(f -> fooStr.contains(f.getId()))
.collect(Collectors.toMap(Foo::getId, f -> f));发布于 2018-07-06 22:57:26
当在最终输出中有条件地包含项时,使用filter,当从流到映射时使用Collectors.toMap。以下是你最后的结局:
Map<String,Foo> filterMethod (final Set<String> fooStr) {
List<Foo> fDefs; // list of Foo objects
return fDefs.stream()
.filter(foo -> fooStr.contains(foo.getId()))
.collect(Collectors.toMap(Foo::getId, Function.identity()));
}发布于 2018-07-07 00:20:07
虽然ggreiner已经提供了一个工作解决方案,但是当存在复制时,您最好处理它,包括一个mergeFunction。
直接使用Collectors.toMap(keyMapper,valueMapper),某一天或另一天,您将遇到以下问题。
如果映射的密钥包含重复项(根据IllegalStateException (对象)),则在执行集合操作时抛出一个Object.equals。如果映射的键可能有重复项,则使用toMap(函数、函数、BinaryOperator)。
根据OP的解决方案,我认为最好用
import static java.util.stream.Collectors.*; // save some typing and make it cleaner;
fDefs.stream()
.filter(foo -> fooStr.contains(foo.getId()))
.collect(toMap(Foo::getId, foo -> foo, (oldFoo, newFoo) -> newFoo));https://stackoverflow.com/questions/51218499
复制相似问题