关于并行流parallelStream的用法的一些问题

683 阅读1分钟

前言

今天逛论坛关于parallelStream并行流一些内容,发现论坛里关于这方面的问题,他们给出的代码是这样的

@Test
public void testStream() {
    List<Integer> list = new ArrayList<>();
    for (int i = 0; i < 10000; i++) {
        list.add(i);
    }
    System.out.println(list.size());
    List<Integer> streamList = new ArrayList<>();
    list.parallelStream().forEach(streamList::add);
    System.out.println(streamList.size());
}

这样的

List<Integer> integers = new ArrayList<>();
for (int i = 0; i < 1000; i++ ) {
    integers.add(i);
}
List<String> strings = new ArrayList<>();
integers.parallelStream().forEach(i -> strings.add(i.toString()));
System.out.println(strings);

当然这些都是一些错误写法,他们给出的解决方案是使用一些线程安全的集合比如Collections.synchronizedList或者CopyOnWriteArrayList 其实这些都是多线程操作共享变量没加锁导致的问题,不是parallelstream本身的问题,我们再来看他们的代码就是创建新集合然后用并行流处理把里面的元素add到新集合中,关于这种映射的操作是推荐使用map函数进行操作的,其实通过这些代码可以发现他们对lambda和stream流的认知都是一知半解的完全是为了用而用根本就不理解下面给出解决方案 第一段代码可以改为

//这是原来的
@Test
public void testStream() {
    List<Integer> list = new ArrayList<>();
    for (int i = 0; i < 10000; i++) {
        list.add(i);
    }
    System.out.println(list.size());//打印10000
    List<Integer> streamList = new ArrayList<>();
    list.parallelStream().forEach(streamList::add);
    System.out.println(streamList.size());//可能导致数据丢失或者下标越界
}
//修改后
@Test
public void testStream() {
    List<Integer> list = new ArrayList<>();
    for (int i = 0; i < 10000; i++) {
        list.add(i);
    }
   System.out.println(list.size());//打印10000
   List<Integer> streamList = list.parallelStream()
   .map(Integer::new).collect(Collectors.toList());
   System.out.println(streamList.size());//打印10000
}

第二段代码

//原来的
List<Integer> integers = new ArrayList<>();
for (int i = 0; i < 1000; i++ ) {
    integers.add(i);
}

List<String> strings = new ArrayList<>();
integers.parallelStream().forEach(i -> strings.add(i.toString()));
System.out.println(strings);//可能导致数据丢失或者下标越界
//修改后
List<Integer> integers = new ArrayList<>();
for (int i = 0; i < 1000; i++ ) {
    integers.add(i);
}
List<String> strings = integers.parallelStream()
//这里使用了方法引用等同于map(s->s.toString())
.map(Objects::toString)
.collect(Collectors.toList());
System.out.println(strings);//打印结果[0, 1, 2...998, 999]

总结

我们使用lambda编写代码时应该多想一下我们为什么这么写而不是为了写而写,想说的就这么多了最后祝所有程序猿,写代码行行无Bug