我在谈论Java上的函数式编程。让我们说我有一个ArrayList并想输入一些值。问题在于我无法想出一种不违反范式原则的方法。到目前为止,我可以猜测我应该用递归函数替换迭代,但是将输入值传递给数组呢?如果我这样做:
Scanner in = new Scanner(System.in);
然后:
MyArrayList.add(in.NextDouble( ) );
我实际上是在使用变量,所以我猜这个解决方案是不可接受的。如果我尝试使用JOptionPane获取输入,则相同,因为我必须将字符串转换为数字,并且需要使用变量。有没有办法从键盘输入值到ArrayList而不涉及变量或循环?如果不是,那么面对这样的案例时,FP的标准做法是什么?只是视而不见,打破这个原则一次?
答案 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
个实例并将双打收集到列表中。