如何在不违反功能编程原理的情况下将值读取为arraylist



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

最新更新