java8之steam流的一些用法

前言

java8新增的功能中,增加了stream流API,那么stream流究竟有什么作用了,该怎么使用呢?

什么是流

所谓流就是数据的渠道,流代表的是一个对象的序列,它和java IO流是两个不同的东西,这里的流指的是某个流类型的对象。

stream常用的方法

// 产生一个新流,包含调用流中满足predicate的谓词元素 中间操作
Stream<T> filter(Predicate<? super T> predicate);

// 产生一个新流,对调用流中元素映射mapper 中间操作
<R> Stream<R> map(Function<? super T, ? extends R> mapper);

// 产生一个新的intStream流,对调用流中元素映射mapper 中间操作
IntStream mapToInt(ToIntFunction<? super T> mapper);

// 产生一个按一定方式排序的新流 中间操作
 Stream<T> sorted(Comparator<? super T> comparator);
 
// 遍历流中元素 终端操作
void forEach(Consumer<? super T> action);

// 获取流中最大,最小值 终端操作
Optional<T> max(Comparator<? super T> comparator);

缩减操作

用流API的术语来形容,缩减操作就是把一个流缩减为一个值,先来看看stream接口中的reduce方法

Optional<T> reduce(BinaryOperator<T> accumulator);
T reduce(T identity, BinaryOperator<T> accumulator);
<U> U reduce(U identity,BiFunction<U, ? super T, U> accumulator,BinaryOperator<U> combiner);

第一个方法返回要给optionanl对象,第二个方法返回的是T类型,就是流中元素类型;accumulator的类型是扩展了BiFunction函数式接口

    R apply(T t, U u);

apply对t参数和u参数应用到同一个函数上,并返回结果r,而BinaryOperator扩展BiFunction时所有参数都是T

所以通过reduce缩减操作后得到的结果取决于具体使用reduce方法

缩减操作三个约束

List<Integer> s = new ArrayList<>();
s.add(1);s.add(4);
s.add(5);s.add(6);
s.add(3);s.add(2);
Optional sum = s.stream().reduce((a,b) -> a + b);

if (sum.isPresent()) {
    System.out.println("list sum is " + sum.get());
}

Integer sum2 = s.stream().reduce(0, (a,b) -> a+b);
System.out.println("list sum is " + sum2);

Optional sum3 = s.stream().reduce((a, b) -> a * b);
System.out.println("list sum is " + sum3.get());

 Integer sum4 = s.stream().reduce(1, (a,b) -> a*b);
System.out.println("list sum is " + sum4);

结果:

此处输入图片的描述

并行流

获取方式:1通过parallel()方法获取流 2通过collection接口提供的parallelStream方法获取并行流 上面的例子使用并行流操作:

 List<Integer> s = new ArrayList<>();
    s.add(1);
    s.add(2);
    s.add(3);
    s.add(4);
    s.add(5);
    s.add(6);
    Optional sum = s.parallelStream().reduce((a,b) -> a + b);

    if (sum.isPresent()) {
        System.out.println("list sum is " + sum.get());
    }

    Integer sum2 = s.parallelStream().reduce(0, (a,b) -> a+b);
    System.out.println("list sum is " + sum2);

    Optional sum3 = s.parallelStream().reduce((a, b) -> a * b);
    System.out.println("list sum is " + sum3.get());

     Integer sum4 = s.parallelStream().reduce(1, (a,b) -> a*b);
    System.out.println("list sum is " + sum4);

结果是一样的,应用到并行流的操作都必须符合缩减操作的三个约束条件,使得并行流上获得结果和顺序流是一样的

在使用并行流的时候,如果集合和数组中元素是有序的出来的流也是有序的,如果时无序的,出来的流也是无序的,有时候流时无序的能获得性能上的提升,unordered()方法将流转换为无序流

映射

<R> Stream<R> map(Function<? super T, ? extends R> mapper);

R表示新的流元素类型,T表示映射前流元素类型,map获取流中元素某个小元素类型,并返回这个类型的一个新流

获取所有苹果的重量总和

List<Integer> wight = apples.stream().map(Apple::getWight).collect(Collectors.toList());

收集

Collectors类是一个最终类,里面提供大量静态收集器方法,可借此实现各种复杂功能

收集苹果的名和产地

List<String> names = apples.stream().map(Apple::getName).collect(Collectors.toList());
Set<String> nameSets = apples.stream().map(Apple::getCountry).collect(Collectors.toSet());

TODO 未完待续

流使用例子

// List中去除某值形成List
List<Apple> apples = new ArrayList<Apple>();
List<Apple> apples2 = new ArrayList<Apple>();
Apple a = new Apple();
apples.add(a);
List<Integer> wight = apples.stream().map(Apple::getWight).collect(Collectors.toList());
// List 转map
Map<Integer, String> map = apples.stream().collect(Collectors.toMap(Apple::getWight, Apple::getCountry));

// List中字段求和
Integer test = apples.stream().collect(Collectors.summingInt(Apple::getWight));
// 获取比当前时间大的最小的时间
List<Date> dateList = new ArrayList<>();

Date mindate = dateList.stream().filter(date -> date.getTime() > System.currentTimeMillis()).min(Comparator.comparing(Date::getTime)).get();

// 求交集
List<Apple> list3 = apples.stream().filter(item -> apples2.contains(item)).collect(Collectors.toList());
// 球最小
Apple minAppple = apples.stream().min(Comparator.comparing(Apple::getWight)).get();
// 求差集
List<Apple> list4 = apples.stream().filter(item -> !apples2.contains(item)).collect(Collectors.toList());
// 求去重并集
apples.addAll(apples2);
apples.stream().distinct().collect(Collectors.toList());

//循环输出
apples.stream().forEach(System.out::println);

// 分组
Map<String, List<Apple>> result2 = apples.stream().collect(Collectors.groupingBy(Apple::getCountry));

```