[英]JAVA 8 : need to perform List iteration in stream and convert list of another object
[英]Java Stream multi list iteration
我有 2 个列表。 1 个列表包含 Id,另一个列表充满Foo
对象,称为列表 A。 Foo
类如下所示:
public class Foo {
private String id;
/* other member variables */
Foo(String id) {
this.id = id;
}
public String getId() {
return id;
}
}
我有一个简单的 id 列表,如List<Integer>
,将其称为列表 B。我想要做的是一次迭代列表 B 一个元素,获取 id,将其与列表 A 进行比较,然后获取具有等效项的Foo
对象id,然后将Foo
对象添加到新列表,即列表 C。
我正在尝试连接流,但我是流的新手,并且我对map
、 filter
、 forEach
等所有方法陷入了困境。 我不确定何时使用什么。
最简单的方法就是您在帖子中的内容:遍历 id,选择第一个具有该 id 的Foo
,如果找到,则将其收集到List
。 放入代码中,它看起来像下面这样:每个 id 都映射到相应的Foo
,通过在具有该 id 的 foo 上调用findFirst()
找到该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
并过滤掉表示未找到Foo
null
元素。
另一种完全不同的方法不是遍历 id 并搜索Foo
,而是过滤具有包含在通缉列表中的 id 的Foo
。 方法的问题在于,它需要对输出列表进行排序,以便结果列表的顺序与 id 的顺序相匹配。
我会像这样实现它:
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());
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.