【问题标题】:Stream to compare two list by index流按索引比较两个列表
【发布时间】:2021-08-02 13:53:52
【问题描述】:

我有 2 个不同的列表:List1List2,我想对元素具有相同 getName() 值的每个索引执行一个操作:

for (int i = 0; i < 5; i++) { 
    if (list1.get(i).getName().equals(list2.get(i).getName())) {
        // TODO
    }
}

有没有办法使用 Java 流来做到这一点?我已经尝试过逻辑:

if (List1().stream().anymatch(x -> List2().stream().anymatch(y -> x.getName().equals(y.getName))))) {
    // TODO
}

这可行,但List1 的第一个对象(索引)与List2 的每个对象(索引)进行比较。

我需要的是List1 的第一个对象(索引)与List2 的第一个对象(索引)进行比较,第二个索引到第二个等等。 如何使用流而不是 for 循环来编写 if 逻辑。

【问题讨论】:

  • 请勿将代码发布为图片
  • 使用IntStream 生成索引,例如IntStream.range(0, 5),然后酌情使用mapmapToObjforEach 并访问obj1.get(i)obj2.get(i)
  • IntStream.range(0, a.length).mapToObj(i -&gt; a[i].getName() == b[i].getName()).collect(Collectors.toList()); 是这样的吗?
  • 条件检查后你想要什么。您是否要将数据存储在另一个列表中。请具体针对您的问题并转到此链接。你的问题在这里解释stackoverflow.com/questions/57252497/…
  • 您好,很抱歉给您带来不便,现在为问题添加了更多信息。请帮我解决这个问题。

标签: java stream


【解决方案1】:

一种解决方案是使用第三方库,该库能够将zip 流对转换为单个流对。使用这种方法,两个流将被压缩到包含元素对的单个流中,具有相同名称的对将通过调用 Stream.filter() 保留,然后最后过滤的剩余元素对将应用操作给他们。

堆栈溢出答案Zipping streams using JDK8 with lambda (java.util.stream.Streams.zip) 包含以这种方式压缩两个流的各种解决方案。

番石榴

Google 的 Guava 库提供了 Streams.zip 方法:

Streams.zip(list1.stream(), list2.stream(), Map::entry)
        .filter(e -> e.getKey().getName().equals(e.getValue().getName()))
        .forEachOrdered(e ->
                System.out.println("Match: " + e.getKey() + ", " + e.getValue()));

StreamEx

StreamEx库提供了多种压缩方式,包括StreamEx.zipEntryStream.zip

EntryStream.zip(list1, list2)
        .filterKeyValue((k, v) -> k.getName().equals(v.getName()))
        .forKeyValue((k, v) -> System.out.println("Match: " + k + ", " + v));

【讨论】:

    【解决方案2】:

    一种方法是通过索引而不是列表进行流式传输,并使用List.get(i) 从每个List 中检索元素。

    IntStream.range(0, list1.size())
            .mapToObj(i -> Map.entry(list1.get(i), list2.get(i)))
            .filter(e -> e.getKey().getName().equals(e.getValue().getName()))
            .forEachOrdered(e ->
                    System.out.println("Match: " + e.getKey() + ", " + e.getValue()));
    

    IntStream.range(0, list1.size())
            .filter(i -> list1.get(i).getName().equals(list2.get(i).getName()))
            .forEachOrdered(i ->
                    System.out.printf("Match at index %s: %s, %s\n", i, list1.get(i), list2.get(i)));
    

    请注意,要使这种方法有效,列表必须支持快速(例如恒定时间)随机访问。这通常意味着任何实现了RandomAccess 接口的列表,例如ArrayListArrays.asList()

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-03
      • 1970-01-01
      • 2019-01-03
      • 1970-01-01
      • 2012-07-10
      • 1970-01-01
      相关资源
      最近更新 更多