我在说Java上的功能编程。假设我有一个arraylist,并且想输入一些值。问题在于,我想不出一种不会打破范式原理的方法。到目前为止,我可以猜测我应该用递归功能代替迭代,但是将输入值传递给数组呢?如果我做类似的事情:
Scanner in = new Scanner(System.in);
,然后:
MyArrayList.add(in.NextDouble( ) );
我实际上正在使用一个变量,所以我想这个解决方案是不可接受的。同样,如果我尝试使用joptionpane获取输入,因为我必须将字符串转换为数字,并且需要使用变量。有没有办法将值从键盘转到阵列列表而不涉及变量或循环?如果不是,那么在面对这样的案件时,FP的标准做法是什么?只是视而不见,一次打破原则?
,假设您想从 Scanner
获得10个 double
值。
您可以使用流:
List<Double> myArrayList = IntStream.range(0, 10)
.mapToObj(i -> in.nextDouble())
.collect(Collectors.toList());
shmosel评论,这可能是一种更好的方法:
List<Double> myArrayList = DoubleStream
.generate(in::nextDouble)
.limit(10)
.boxed()
.collect(Collectors.toList());
或如果您想要一个原始数组,请简单:
double[] myArrayList = DoubleStream.generate(in::nextDouble).limit(10).toArray();
update
现在,如果您真正的想在Java中进行功能编程,则不应在Java Runtime库中使用可变的集合。而是寻找功能性编程库,例如vavr:
vavr Core是Java的功能库。它有助于减少代码量并增加鲁棒性。迈向功能编程的第一步是开始思考不变的值。 VAVR提供不变的集合以及必要的功能和控制结构以在这些值上操作。结果很美,只是工作。
免责声明:我不知道vavr。在我当前的工作中,在Java中不需要纯粹的功能编程。
另一种方式,只是为了娱乐,也许是一些理论上的兴趣:
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
实例并将双打收集到列表中。