Java Stream多列表迭代

时间:2016-03-16 14:27:36

标签: java list java-8 iteration java-stream

我有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.

我正在尝试连接流,但我是流媒体的新手,我陷入了Foomapfilter等所有方法的困境。我不知道什么时候用。

2 个答案:

答案 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());