通过< String>Java 8流填充现有Set

bis0qfac  于 2023-05-27  发布在  Java
关注(0)|答案(2)|浏览(187)

我是Java流和函数式编程的新手,我想知道我的问题是否会有一个有效的用例,或者它只是没有意义。我有下面的代码,从数组中得到一个Set

public static void main(String[] args) {
        String []arr = {"a","abc","b","cd"};
        Set<String> dict = new HashSet<>();
        Arrays.stream(arr).map(item->{
            System.out.println(item);
            dict.add(item);
            return dict;
        });

//        dict = Arrays.stream(arr).collect(Collectors.toSet());
        System.out.println(dict);
    }

这给了我一个空洞的命令。如果我用倒数第二行的方法来做,它会起作用。有没有一种方法可以改变已经示例化的dict,它是在map函数中填充的流之外示例化的?

bfnvny8b

bfnvny8b1#

1.在问题被编辑之前,注解部分没有编译,因为dict必须是final或有效的final。请参阅此answer了解更多信息。
1.使用Stream API的少数规则之一是避免副作用。JavaDoc for java.util.stream包通过示例很好地描述了它:
一般来说,不鼓励流操作的行为参数中的副作用,因为它们通常会导致无意中违反无状态要求,以及其他线程安全隐患。
1.每个Stream的主旨是通过过滤、Map、缩减或高级收集等操作返回一个新的集合/值。它从来没有打算修改现有的。如何将数组arr转换为集合的正确方法是:

Set<String> dict = Arrays.stream(arr)
      .peek(item -> System.out.println(item)) // optional for debugging
      .collect(Collectors.toSet());
bfrts1fy

bfrts1fy2#

Stream.map()是一个 * 中间操作 *,这意味着它只执行管道中的一个步骤,但当您调用它时,它不会执行任何操作。您需要一个 * 终端操作 * 来使流工作。在这种情况下,可以使用forEachOrdered()

Arrays.stream(arr)
        .peek(System.out::println)
        .forEachOrdered(dict::add);

注意:我假设您需要修改现有集合而不是生成新集合是有原因的。否则,就像另一个答案中建议的那样使用collect()

相关问题