我有2个清单。 1个列表是Ids,另一个列表中有Foo
个对象,称之为列表A. Foo
类看起来像这样:
public class Foo {
private String id;
/* other member variables */
Foo(String id) {
this.id = id;
}
public String getId() {
return id;
}
}
我有一个像List<Integer>
这样的id的简单列表,称之为列表B.我想要做的是一次遍历列表B一个元素,抓取id,将它与列表A进行比较并抓取{具有等效id的{1}}对象,然后将Foo
对象添加到新列表中,列出C.
我正在尝试连接流,但我是流媒体的新手,我陷入了Foo
,map
,filter
等所有方法的困境。我不知道什么时候用。
答案 0 :(得分:1)
直截了当的方式就是你在帖子中的内容:循环id,选择第一个具有该ID的--local-infile=1
,如果找到,则将其收集到Foo
。放入代码中,它看起来如下所示:每个id都映射到通过在具有该id的foos上调用findFirst()
找到的相应List
。这会返回Foo
过滤掉Optional
不存在的Foo
。
List<Integer> ids = Arrays.asList(1, 2, 3);
List<Foo> foos = Arrays.asList(new Foo("2"), new Foo("1"), new Foo("4"));
List<Foo> result =
ids.stream()
.map(id -> foos.stream().filter(foo -> foo.getId().equals(id.toString())).findFirst())
.filter(Optional::isPresent)
.map(Optional::get)
.collect(Collectors.toList());
这种方法的一个大问题是你需要遍历foos
列表的次数与要查看的id一样多。更好的解决方案是首先创建一个查找Map
,其中每个ID都映射到Foo
:
Map<Integer, Foo> map = foos.stream().collect(Collectors.toMap(f -> Integer.valueOf(f.getId()), f -> f));
List<Foo> result = ids.stream().map(map::get).filter(Objects::nonNull).collect(Collectors.toList());
在这种情况下,我们会查找Foo
并过滤掉null
元素,这意味着找不到Foo
。
另一种完全不同的方法不是遍历id并搜索Foo
,而是过滤{id}包含在所需id列表中的id Foo
。方法的问题在于,它需要对输出列表进行排序,以便结果列表的顺序与id的顺序相匹配。
答案 1 :(得分:0)
我会像这样实现它:
List<Foo> list = Arrays.asList(
new Foo("abc"),
new Foo("def"),
new Foo("ghi")
);
List<String> ids = Arrays.asList("abc", "def", "xyz");
//Index Foo by ids
Map<String, Foo> map = list.stream()
.collect(Collectors.toMap(Foo::getId, Function.identity()));
//Iterate on ids, find the corresponding elements in the map
List<Foo> result = ids.stream().map(map::get)
.filter(Objects::nonNull) //Optional...
.collect(Collectors.toList());