代码之家  ›  专栏  ›  技术社区  ›  George S.

如何在不违背函数编程原则的情况下将值读入ArrayList?

  •  1
  • George S.  · 技术社区  · 7 年前

    我说的是Java上的函数式编程。假设我有一个ArrayList,想输入几个值。问题是,我想不出一种不打破范式原则的方法。到目前为止,我可以猜到我应该用递归函数代替迭代,但是把输入值传递给数组呢?如果我这样做:

    Scanner in = new Scanner(System.in); 
    

    然后:

    MyArrayList.add(in.NextDouble( ) ); 
    

    我实际上使用了一个变量,所以我想这个解决方案是不可接受的。如果我尝试使用JOptionPane获取输入,也是一样的,因为我必须将字符串转换为数字,这需要使用变量。有没有一种方法可以在不涉及变量或循环的情况下将值从键盘输入到ArrayList?如果不是,那么面对这样的案件,FP的标准做法是什么?只是睁一只眼闭一只眼,这一次违反了原则?

    2 回复  |  直到 7 年前
        1
  •  3
  •   Andreas dfa    7 年前

    假设你想得到10分 double 中的值 Scanner

    然后您可以使用 streams :

    List<Double> myArrayList = IntStream.range(0, 10)
            .mapToObj(i -> in.nextDouble())
            .collect(Collectors.toList());
    

    commented by shmosel ,这可能是更好的方法:

    List<Double> myArrayList = DoubleStream
            .generate(in::nextDouble)
            .limit(10)
            .boxed()
            .collect(Collectors.toList());
    

    或者,如果需要基元数组,只需执行以下操作:

    double[] myArrayList = DoubleStream.generate(in::nextDouble).limit(10).toArray();
    

    使现代化

    现在,如果你 真正地 要在Java中进行函数式编程,不应该使用Java运行时库中的可变集合。相反,请查找函数式编程库,例如 Vavr :

    Vavr核心是一个Java函数库。它有助于减少代码量并提高健壮性。函数式编程的第一步是开始用不变的值进行思考。 Vavr提供不可变集合 以及对这些值进行操作所需的功能和控制结构。结果很漂亮,很好用。

    免责声明:我不知道Vavr。在我目前的工作中,我不需要纯Java函数编程。

        2
  •  0
  •   fps    7 年前

    另一种方式,只是为了好玩,也许是出于某种理论兴趣:

    try (Stream<String> tokens = new Scanner(System.in).tokens()) {
    
        List<Double> list = tokens.takeWhile(t -> !"-".equals(t))
                .map(Double::parseDouble)
                .collect(Collectors.toList());
    
        System.out.println(list);
    }
    

    这将从标准输入中读取标记,直到读取连字符,然后将其解析为 Double 实例并将双精度值收集到列表中。