【问题标题】:Stream foreach with multiple values?具有多个值的流foreach?
【发布时间】:2016-03-21 07:26:56
【问题描述】:

我有一个ArrayList<Integer>,其中包含偶数个元素。如何使用 Stream.forEach 一次解析 2 个值?

x.forEach((a, b) -> System.out.println(a.toString() + "-" + b.toString());

这不起作用。

【问题讨论】:

  • 整数值,例如:1、2、3、4、5、6
  • @BorisvanKatwijk,这个问题是不相关的:使用了重叠对。在这里,我假设 OP 想要使用非重叠对。

标签: java foreach java-stream


【解决方案1】:

您可以将以下辅助方法添加到项目的某个实用程序类中:

public static <T> void forPairs(List<T> list, BiConsumer<T, T> action) {
    IntStream.range(0, list.size()/2)
             .forEach(i -> action.accept(list.get(i*2), list.get(i*2+1)));
}

并像这样使用它:

List<Integer> list = Arrays.asList(1, 3, 5, 2, 1, 6);
forPairs(list, (a, b) -> System.out.println(a + "-" + b));

【讨论】:

    【解决方案2】:

    如果你想为了使用流而使用流,你可以:

    1. 编写一个相当困难的自定义收集器来收集对,然后重新流式传输它们并执行您的操作,或者
    2. 迭代索引而不是元素,这里提供了答案(但它不是您感兴趣的对象的流)。

    这里的问题是 Streams 是为无副作用的无状态管道操作而设计的,而不是用于组合元素(除了一些例外)。 docs 相当精致。

    在这里使用iterator 会更合适:

    Iterator<Integer> iterator = Arrays.asList(1, 2, 3, 4, 5, 6).iterator();
    while(iterator.hasNext()) {
        System.out.println(iterator.next().toString() + "-" + iterator.next().toString());
    }
    

    注意:如果列表大小为奇数,这将抛出 NoSuchElementException。如果需要,防御性检查很容易编写。

    【讨论】:

      【解决方案3】:

      这样就可以了:

      IntStream.range(0, list.size() - 1)
      .filter(i -> i % 2 == 0)
      .forEach(i -> System.out.println(list.get(i) + "-" + list.get(i + 1)));
      

      它将从列表 [1, 2, 3, 4, 5, 6] 中产生以下输出:

      1-2
      3-4
      5-6
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-10-28
        • 2022-11-26
        • 2015-01-22
        • 1970-01-01
        • 1970-01-01
        • 2023-03-30
        • 2020-03-15
        相关资源
        最近更新 更多