Java Stream流的使用
流相关的方法可以分为三种类型,分别是:获取Stream流、中间方法、终结方法。中间方法会返回当前流,可以方便的进行链式调用。
流不可重复使用,否则会报错:
java.lang.IllegalStateException: stream has already been operated upon or closed
// 获取流的方式
List<Integer> list = Arrays.asList(1, 2, 4, 5, 5, 6, 7, 0);
String [] strArr = new String[]{"aaa", "bbb", "aaa"};
Stream<Integer> stream = list.stream(); // 从列表获取流
Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5); // 从可变参数获取流
Stream<String> arrStream = Stream.of(strArr); // 从数组获取流
常见的中间方法:
方法 | 用途 |
---|---|
Stream<T> filter(Predicate<? super T> predicate) |
用于对流中的数据进行过滤。 |
Stream<T> limit(long maxSize) |
获取前几个元素 |
Stream<T> skip(long n) |
跳过前几个元素 |
Stream<T> distinct() |
去除流中重复的元素。依赖(hashCode和equals方法) |
static <T> Stream<T> concat(Stream a, Stream b) |
合并a和b两个流为一个流(也会遍历流,不可执行两次) |
Stream<T> sorted(Comparator<? super T> comparator) |
对元素进行合并 |
Stream map(Function<? super T, ? extends R> mapper) |
对每个元素进行处理 |
// filter()
stream.filter(x -> x > 0).filter(x -> x < 5).forEach(System.out::println);
// limit()
integerStream.limit(3).forEach(System.out::println);
// skip()
integerStream.skip(3).forEach(System.out::println);
// 去重
arrStream.distinct().forEach(System.out::println);
// 可将不同类型的Stream拼接到一起,不能执行两次
Stream<? extends Serializable> concat1 = Stream.concat(stream, arrStream);
// 将相同元素拼接到一起后,可以直接用一个类型接收
Stream<Integer> concat = Stream.concat(stream, integerStream);
// 排序
stream.sorted((x, y)->x - y).forEach(System.out::println);
// map()
List<Integer> collect = stream.map((Integer x) -> x * x).collect(Collectors.toList());
常见的收集函数:
方法 | 用途 |
---|---|
public static <T> Collector toList() |
把元素收集到List集合中 |
<A> A[] toArray(IntFunction<A[]> generator) |
把元素收集到数组中 |
public static <T> Collector toSet() |
把元素收集到Set集合中 |
public static Collector toMap(Function keyMapper , Function valueMapper) |
把元素收集到Map集合中 |
Collectors.groupingBy() |
对元素进行分组 |
// 收集成List
List<Digit> collect = list.stream().map(Digit::new).collect(Collectors.toList());
// 收集成数组,两个方法等效,务必要转换成对应的数组类型。
Integer[] integers = list.stream().toArray(length -> new Integer[length]);
Integer[] digits = list.stream().toArray(Integer[]::new); // 务必要用对应的类型
// 转换成Set
Set<Integer> collect1 = list.stream().collect(Collectors.toSet());
Digit [] data = new Digit[]{
new Digit("aaa", 10),
new Digit("bbb", 20)
};
// 转换成 Map
Map<String, Integer> collect3 = Stream.of(data).collect(Collectors.toMap(Digit::getDesc, Digit::getValue));
// 分组
ConcurrentMap<String, List<Employee>> clusterMap = clusters.stream().
collect(Collectors.groupingByConcurrent(Employee::getCity));