Java_并发流

一.并发流

1.概述

当需要对存在于集合或数组中的若干元素进行并发操作时,简直就是噩梦!我们需要仔细考虑多线程环境下的原子性、竞争甚至锁问题,即便是java.util.concurrent.ConcurrentMap<K, V>接口也必须谨慎地正确使用。

而对于Stream流来说,这很简单。

转换为并发流

Stream的父接口java.util.stream.BaseStream中定义了一个parallel方法:

S parallel();

只需要在流上调用一下无参数的parallel方法,那么当前流即可变身成为支持并发操作的流,返回值仍然为Stream类型。例如:

import java.util.stream.Stream;

public class DemoStreamParallel {
    public static void main(String[] args) {
        Stream<Integer> stream = Stream.of(10, 20, 30, 40, 50).parallel();
    }
}

直接获取并发流

在通过集合获取流时,也可以直接调用parallelStream方法来直接获取支持并发操作的流。方法定义为:

default Stream<E> parallelStream() {...}
import java.util.ArrayList;
import java.util.Collection;
import java.util.stream.Stream;

public class DemoStreamParallel {
    public static void main(String[] args) {
        Collection<String> coll = new ArrayList<>();
        Stream<String> stream = coll.parallelStream();
    }
}

使用并发流

多次执行下面这段代码,结果的顺序在很大概率上是不一定的:

import java.util.stream.Stream;

public class DemoStreamParallel {
    public static void main(String[] args) {
        Stream.of(10, 20, 30, 40, 50, 60, 70, 80, 90, 100)
          	  .parallel()
          	  .forEach(System.out::println);
    }
}

2.收集Stream结果

2.1 收集到集合中

Stream流提供collect方法,其参数需要一个java.util.stream.Collector<T,A, R>接口对象来指定收集到哪种集合中。幸运的是,java.util.stream.Collectors类提供一些方法,可以作为Collector接口的实例:

  • public static Collector<T, ?, List> toList():转换为List集合。
  • public static Collector<T, ?, Set> toSet():转换为Set集合。
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class DemoStreamCollect {
    public static void main(String[] args) {
        Stream<String> stream = Stream.of("10", "20", "30", "40", "50");
        List<String> list = stream.collect(Collectors.toList());
        Set<String> set = stream.collect(Collectors.toSet());
    }
}

2.2 收集到数组中

Stream提供toArray方法来将结果放到一个数组中,由于泛型擦除的原因,返回值类型是Object[]的:

Object[] toArray();
import java.util.stream.Stream;

public class DemoStreamArray {
    public static void main(String[] args) {
        Stream<String> stream = Stream.of("10", "20", "30", "40", "50");
        Object[] objArray = stream.toArray();
    }
}

2.3 解决泛型数组问题

有了Lambda和方法引用之后,可以使用toArray方法的另一种重载形式传递一个IntFunction<A[]>的函数,继而从外面指定泛型参数。方法签名:

<A> A[] toArray(IntFunction<A[]> generator);

有了它,上例代码中不再局限于Object[]结果,而可以得到String[]结果:

import java.util.stream.Stream;

public class DemoStreamArray {
    public static void main(String[] args) {
        Stream<String> stream = Stream.of("10", "20", "30", "40", "50");
        String[] strArray = stream.toArray(String[]::new);
    }
}

既然数组也是有构造器的,那么传递一个数组的构造器引用即可。

Java仍然没有泛型数组,原因同样是泛型擦除。

3.练习:将数组元素加到集合中

请通过Stream流的方式,将下面数组当中的元素添加(收集)到List集合当中:


public class DemoCollect {
    public static void main(String[] args) {
        int[] array1 = { 10, 20, 30, 40, 50 };
        
        Integer[] array2 = {10,20,30,40,50};
        
        String[] array3 = { "Java", "Groovy", "Scala", "Kotlin" };
    }
}

解答:

首先需要将数组转换成为流,然后再通过collect方法收集到List集合中:

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class DemoCollect {
    public static void main(String[] args) {
    	int[] array1 = { 10, 20, 30, 40, 50 };
    	List<int[]> list1 = Stream.of(array1).collect(Collectors.toList());
    	
    	Integer[] array2 = {10,20,30,40,50};
    	List<Integer> list2 = Stream.of(array2).collect(Collectors.toList());
    	
        String[] array3 = { "Java", "Groovy", "Scala", "Kotlin" };
        List<String> list3 = Stream.of(array3).collect(Collectors.toList());
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值