如何在不破坏函数式编程原理的情况下将值读入ArrayList?

时间:2018-04-05 23:21:39

标签: java functional-programming

我在谈论Java上的函数式编程。让我们说我有一个ArrayList并想输入一些值。问题在于我无法想出一种不违反范式原则的方法。到目前为止,我可以猜测我应该用递归函数替换迭代,但是将输入值传递给数组呢?如果我这样做:

Scanner in = new Scanner(System.in); 

然后:

MyArrayList.add(in.NextDouble( ) ); 

我实际上是在使用变量,所以我猜这个解决方案是不可接受的。如果我尝试使用JOptionPane获取输入,则相同,因为我必须将字符串转换为数字,并且需要使用变量。有没有办法从键盘输入值到ArrayList而不涉及变量或循环?如果不是,那么面对这样的案例时,FP的标准做法是什么?只是视而不见,打破这个原则一次?

2 个答案:

答案 0 :(得分:3)

假设您想从double获得10个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中的纯函数式编程。

答案 1 :(得分:0)

另一种方式,只是为了娱乐而且可能有一些理论上的兴趣:

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个实例并将双打收集到列表中。