代码之家  ›  专栏  ›  技术社区  ›  Koray Tugay

使用IntStream和forEach创建整数列表的方法有什么错误?

  •  8
  • Koray Tugay  · 技术社区  · 6 年前

    class ${
        public static void main(String[] _) {
            final List<Integer> ints = new ArrayList<>();
            IntStream.iterate(0, i -> i++).limit(5).forEach(val -> ints.add(val));
            System.out.println(ints);
        }
    }
    

    我期望在控制台中看到以下内容:

    [0, 1, 2, 3, 4]
    

    但实际情况是:

    [0, 0, 0, 0, 0]
    

    4 回复  |  直到 6 年前
        1
  •  3
  •   flakes    6 年前

    您需要返回递增的值。后缀增加了一个局部变量,并返回了非增量值。使用 ++i i++

    final List<Integer> ints = new ArrayList<>();
    IntStream.iterate(0, i -> ++i).limit(5).forEach(val -> ints.add(val));
    System.out.println(ints);
    

    编辑 请参阅johnkugelman关于在函数式编程时使用非变异操作的文章。使用 i + 1 将创建一个新的原语,而不改变参数变量。

        2
  •  35
  •   John Kugelman Michael Hodel    6 年前

    i++ i 之前 它是递增的。您需要使用前缀运算符。

    IntStream.iterate(0, i -> ++i).limit(5).forEach(val -> ints.add(val));
    

    实际上,不要那样做。没有理由变异

    IntStream.iterate(0, i -> i + 1).limit(5).forEach(val -> ints.add(val));
    

    对于连续整数流的特定情况,可以替换 iterate limit 具有 range :

    IntStream.range(0, 5).forEach(val -> ints.add(val));
    

    forEach . 它直接表达了创建一个列表的意图,这同样避免了副作用。

    List<Integer> ints = IntStream.range(0, 5).boxed().collect(Collectors.toList());
    
        3
  •  6
  •   Naman    6 年前

    你用的是后缀 i++ ,而不是前缀 ++i 将值传递给 forEach . 更改为以下内容将为您提供预期的输出:

    IntStream.iterate(0, i -> i + 1).limit(5).forEach(ints::add);
    

    IntStream.iterate 带着一个 IntPredicate 作为:

    IntStream.iterate(0, i -> i < 5, i -> i + 1).forEach(ints::add);
    
        4
  •  1
  •   developer_hatch    6 年前

    你可以用指纹看看发生了什么:

    final List<Integer> ints = new ArrayList<>();
            IntStream.iterate(0, i -> {
                System.out.println(i);
                return i++;
            }).limit(5)
                    .forEach(val -> ints.add(val));
            System.out.println(ints);
    

    final List<Integer> ints = new ArrayList<>();
            IntStream.iterate(0, i -> {
                System.out.println(i);
                return ++i;
            }).limit(5)
                    .forEach(val -> ints.add(val));
            System.out.println(ints);