Java之Stream流的使用

使用好JDK8的新特性会有助于你的编程,Stream流的使用会使集合或数组的操作更加简便,更赏心悦目,相信这篇文章可以使喜欢追求细节完美的人会有所收获。

Java中什么是Stream(流)

Stream是java的1个类, 这个类专门用于程序和外部设备的输入输出(IO). 基本上所有流都在 java.io这个包中.
实际上Stream就是数据在程序和外部设备的单向管道, 流的各种方法相当于管道上的各种按钮.
所谓的外部设备可以包括硬盘文件, 网络设备, 另个程序等. 也就是当前程序之外的数据设备.

要注意在流中操作数据不能影响到原数据 把流理解成为快捷展示的过程或许好理解些(例如看电影),当然也可以通过收集方法来吧数据留存下来不过接收的集合是一个新集合和原来无关。

为什么需要Stream(流)

Stream存在的意义也很简单.

  1. 数据的传输量很大.

  2. 内存有限.

  3. 带宽有限.

而Stream可以1点1点地逐步传输所有数据, 这就是Stream存在的根本意义.

下面简单介绍一下Java中stream流的使用:

1.获取stream流  

方式a:根据Collection获取流
集合创建创建:调用集合的stream方法即可,如 list.stream()

方式b:根据Map获取流
Stream> entryStream = map.entrySet().stream();

方式c:根据静态方法获取流
Stream stream = Stream.of(new Integer[]{1,2});

注:stream流被创建出来之后只能被使用一次,如需再次循环需要再次创建!

方法d:根据Arrays工具类获取

Arrays.stream(new Integer[]{1,2})

2.常用方法介绍:

流的方法被分为中间操作和终端操作,顾名思义,中间操作是指调用方法后生成新的流,可以继续执行操作,而终端操作则是结束流的使用。

中间操作:

1.filter Stream filter(Predicate predicate); 过滤掉不符合的数据 留下true 去除false

2.limit Stream limit(long maxSize); 只取前x条数据 

3.skip Stream skip(long n); 跳过(删除)x条数据 

4.distinct  去重复数据 (底层使用hashCode+equal)

5.sorted  排序 

6.map  Stream map(Function mapper); 对数据重整,生成新的数据流(如何从用户集合流中取出用户年龄作为新的流)

终端操作:

1.count long count(); 统计数据数量

2.forEach void forEach(Consumer action); 对流中每个数据都执行传入的方法

3.anyMatch  至少一个匹配,返回bool

4.allMatch  匹配所有,返回bool

5.collect  可以传入集合中的常用方法

    •  R collect(Collector collector)

      使用 Collector对此流的元素执行 mutable reduction Collector

       R collect(Supplier supplier, BiConsumer accumulator, BiConsumer combiner)

      对此流的元素执行 mutable reduction操作。

static  Collector averagingDouble(ToDoubleFunction mapper) 
返回一个 Collector ,它产生应用于输入元素的双值函数的算术平均值。  
static  Collector averagingInt(ToIntFunction mapper) 
返回一个 Collector ,它产生应用于输入元素的整数值函数的算术平均值。  
static  Collector averagingLong(ToLongFunction mapper) 
返回一个 Collector ,它产生应用于输入元素的长值函数的算术平均值。  
static  Collector collectingAndThen(Collector downstream, Function finisher) 
适应 Collector进行额外的整理转换。  
static  Collector counting() 
返回 Collector类型的接受元件 T计数输入元件的数量。  
static  Collector>> groupingBy(Function classifier) 
返回 Collector “由基团”上的类型的输入元件操作实现 T ,根据分类功能分组元素,并且在返回的结果 Map 。  
static  Collector> groupingBy(Function classifier, Collector downstream) 
返回 Collector “由基团”上的类型的输入元件操作实现级联 T ,根据分类功能分组元素,然后使用下游的指定执行与给定键相关联的值的归约运算 Collector 。  
static >
Collector groupingBy(Function classifier, Supplier mapFactory, Collector downstream) 
返回 Collector “由基团”上的类型的输入元件操作实现级联 T ,根据分类功能分组元素,然后使用下游的指定执行与给定键相关联的值的归约运算 Collector 。  
static  Collector>> groupingByConcurrent(Function classifier) 
返回一个并发 Collector “由基团”上的类型的输入元件操作实现 T ,根据分类功能分组元素。  
static  Collector> groupingByConcurrent(Function classifier, Collector downstream) 
返回一个并发 Collector “由基团”上的类型的输入元件操作实现级联 T ,根据分类功能分组元素,然后使用下游的指定执行与给定键相关联的值的归约运算 Collector 。  
static >
Collector groupingByConcurrent(Function classifier, Supplier mapFactory, Collector downstream) 
返回一个并发 Collector “由基团”上的类型的输入元件操作实现级联 T ,根据分类功能分组元素,然后使用下游的指定执行与给定键相关联的值的归约运算 Collector 。  
static Collector joining() 
返回一个 Collector ,按照遇到的顺序将输入元素连接到一个 String中。  
static Collector joining(CharSequence delimiter) 
返回一个 Collector ,按照遇到的顺序连接由指定的分隔符分隔的输入元素。  
static Collector joining(CharSequence delimiter, CharSequence prefix, CharSequence suffix) 
返回一个 Collector ,它将按照指定的 Collector分隔的输入元素与指定的前缀和后缀进行连接。  
static  Collector mapping(Function mapper, Collector downstream) 
适应一个 Collector类型的接受元件 U至类型的一个接受元件 T通过积累前应用映射函数到每个输入元素。  
static  Collector> maxBy(Comparator comparator) 
返回一个 Collector ,它根据给出的 Comparator产生最大元素,描述为 Optional 。  
static  Collector> minBy(Comparator comparator) 
返回一个 Collector ,根据给出的 Comparator产生最小元素,描述为 Optional 。  
static  Collector>> partitioningBy(Predicate predicate) 
返回一个 Collector ,根据Predicate对输入元素进行 Predicate ,并将它们组织成 Map> 。  
static  Collector> partitioningBy(Predicate predicate, Collector downstream) 
返回一个 Collector ,它根据Predicate对输入元素进行 Predicate ,根据另一个 Collector减少每个分区的值,并将其组织成 Map ,其值是下游缩减的结果。  
static  Collector> reducing(BinaryOperator op) 
返回一个 Collector ,它在指定的 Collector下执行其输入元素的 BinaryOperator 。  
static  Collector reducing(T identity, BinaryOperator op) 
返回 Collector执行下一个指定的减少其输入元件的 BinaryOperator使用所提供的身份。  
static  Collector reducing(U identity, Function mapper, BinaryOperator op) 
返回一个 Collector ,它在指定的映射函数和 BinaryOperator下执行其输入元素的 BinaryOperator 。  
static  Collector summarizingDouble(ToDoubleFunction mapper) 
返回一个 Collector , double生产映射函数应用于每个输入元素,并返回结果值的汇总统计信息。  
static  Collector summarizingInt(ToIntFunction mapper) 
返回一个 Collector , int生产映射函数应用于每个输入元素,并返回结果值的汇总统计信息。  
static  Collector summarizingLong(ToLongFunction mapper) 
返回一个 Collector , long生产映射函数应用于每个输入元素,并返回结果值的汇总统计信息。  
static  Collector summingDouble(ToDoubleFunction mapper) 
返回一个 Collector ,它产生应用于输入元素的双值函数的和。  
static  Collector summingInt(ToIntFunction mapper) 
返回一个 Collector ,它产生应用于输入元素的整数值函数的和。  
static  Collector summingLong(ToLongFunction mapper) 
返回一个 Collector ,它产生应用于输入元素的长值函数的和。  
static >
Collector toCollection(Supplier collectionFactory) 
返回一个 Collector ,按照遇到的顺序将输入元素累加到一个新的 Collection中。  
static  Collector> toConcurrentMap(Function keyMapper, Function valueMapper) 
返回一个并发的 Collector ,它将元素累加到 ConcurrentMap ,其键和值是将所提供的映射函数应用于输入元素的结果。  
static  Collector> toConcurrentMap(Function keyMapper, Function valueMapper, BinaryOperator mergeFunction) 
返回一个并发的 Collector ,它将元素累加到一个 ConcurrentMap ,其键和值是将提供的映射函数应用于输入元素的结果。  
static >
Collector toConcurrentMap(Function keyMapper, Function valueMapper, BinaryOperator mergeFunction, Supplier mapSupplier) 
返回一个并发的 Collector ,它将元素累加到一个 ConcurrentMap ,其键和值是将所提供的映射函数应用于输入元素的结果。  
static  Collector> toList() 
返回一个 Collector ,它将输入元素 List到一个新的 List 。  
static  Collector> toMap(Function keyMapper, Function valueMapper) 
返回一个 Collector ,它将元素累加到一个 Map ,其键和值是将所提供的映射函数应用于输入元素的结果。  
static  Collector> toMap(Function keyMapper, Function valueMapper, BinaryOperator mergeFunction) 
返回一个 Collector ,它将元素累加到 Map ,其键和值是将提供的映射函数应用于输入元素的结果。  
static >
Collector toMap(Function keyMapper, Function valueMapper, BinaryOperator mergeFunction, Supplier mapSupplier) 
返回一个 Collector ,它将元素累加到一个 Map ,其键和值是将所提供的映射函数应用于输入元素的结果。  
static  Collector> toSet() 
返回一个 Collector ,将输入元素 Set到一个新的 Set 。  

6.toArray 转换成数组
Object[] toArray();

Stream的方法:
1.Stream.of(); 获取流形式的对象
2.Stream.concat(stream1, stream2) static Stream concat(Stream a, Stream b) 流合并 (会影响原对象)

流的一些操作实例

package com.youngchan.practice;

import com.sun.org.apache.xpath.internal.SourceTree;

import java.util.*;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author youngchan
 * @version V1.0
 * @Package com.youngchan
 * @date 2020/4/23 18:21
 */
public class Practice {
    public static void main(String[] args) {

        // 使用foreach 遍历的两种方式  方式一
        System.out.println("zero~~~~~~~~~~~~~~~~~~");
        List list = new ArrayList<>();
        list.add("张无忌");
        list.add("周芷若");
        list.add("赵敏");
        list.add("张san");
        list.add(" 张 三 丰  ");
        list.forEach((a)-> System.out.println(a));
        // 方式二
        System.out.println("one~~~~~~~~~~~~~~~~~~");
        list.forEach((a)->{
            if(a.trim().startsWith("张")){
                System.out.println(a);
            }
        });
        //使用 filter进行过滤
        System.out.println("two~~~~~~~~~~~~~~~~~~");
        list.stream().filter(s -> s.startsWith("张")).filter(s -> s.length()==4).forEach(System.out::println);


        // 使用distinct 去重 , map进行拆解筛选对象属性,collect进行收集
        System.out.println("three~~~~~~~~~~~~~~~~~~");
        list.add("张无忌");
        list.stream().filter(s -> s.trim().startsWith("张")).distinct().map(s -> s.toUpperCase()).collect(Collectors.toList()).forEach(System.out::println);

        // 使用count 统计个数
        System.out.println("four~~~~~~~~~~~~~~~~~~");
        System.out.println(list.stream().distinct().count());

        // 使用limit 过滤
        System.out.println("five~~~~~~~~~~~~~~~~~~");
        list.stream().limit(1).forEach(System.out::println);

        // 使用skip 过滤  distinct 和skip连用会用小问题(distinct不改变原集合)
        System.out.println("six~~~~~~~~~~~~~~~~~~");
        System.out.println(list.stream().distinct().collect(Collectors.toList()).stream().count());
        list.stream().distinct().collect(Collectors.toList()).stream().skip(3).limit(1).forEach(System.out::println);


        //使用concat组合  组合后会改变原集合数据
        System.out.println("seven~~~~~~~~~~~~~~~~~~");
        List list2 = new ArrayList<>();
        list.add("孙悟空");
        list.add("猪八戒");
        list.add("沙和尚");
        list.add("唐三藏");
        list.add("白龙马");
        Stream> Slist = Stream.of(list);
        Stream> Slist2 = Stream.of(list2);
        List> result = Stream.concat(Slist, Slist2).filter((a) -> !a.isEmpty()).distinct().collect(Collectors.toList());
        System.out.println(list2.size());
        System.out.println(list.size());
        list.forEach(System.out::println);


        // sorted 排序
        System.out.println("eight~~~~~~~~~~~~~~~~~~");
        list.stream().sorted((a,b)->a.length()-b.length()).forEach(System.out::println);


        // 是否存在 anyMath 匹配  全部是 allMatch 全匹配
        System.out.println("nine~~~~~~~~~~~~~~~~~~");
        System.out.println(list.stream().anyMatch(Predicate.isEqual("孙悟空")));
        System.out.println(list.stream().allMatch(Predicate.isEqual("孙悟空")));


        // 集合排序生成新集合
        System.out.println("ten~~~~~~~~~~~~~~~~~~");

        ArrayList students = new ArrayList<>();
        list.remove(0);
        for (int i = 0; i < list.size(); i++) {
            students.add(new Student(i+ new Random().nextInt(20),list.get(i)));
        }
        System.out.println("排序前学生集合");
        students.forEach((a)-> System.out.print(a+"   ~   "));
        System.out.println("排序后学生集合");
//        Map map = students.stream().sorted((a, b) -> b.getAge() - a.getAge()).collect(Collectors.toMap(Student::getAge, Student::getName));
        Map map = students.stream().sorted((a, b) -> b.getAge() - a.getAge()).collect(Collectors.toMap(Student::getName, Student::getAge));
        System.out.println(map);
        List sortedStudent = students.stream().sorted((a, b) -> a.getAge() - b.getAge()).collect(Collectors.toList());
        sortedStudent.forEach((a)-> System.out.print(a+"   ~   "));


    }

}


  城市分类Person对象: 

   Map> peopleByCity = personStream.collect(Collectors.groupingBy(Person::getCity));  以下将按国家和城市对Person对象进行分类,将两个Collector组合在一起: 

   Map>> peopleByStateAndCity = personStream.collect(Collectors.groupingBy(Person::getState, Collectors.groupingBy(Person::getCity)));  

groupingBy  收集 按照 order_id 作为key  相同的key收集为list
 Map> orderMessageMap = orderList.stream()
          .collect(Collectors.groupingBy(a -> String.valueOf(a.get("ORDER_ID"))));

实体类

package com.youngchan.practice;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Comparator;
import java.util.Objects;

/**
 * @author youngchan
 * @version V1.0
 * @Package com.youngchan.practice
 * @date 2020/4/23 19:40
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student implements Comparator{
   private int age;
   private String name;

    @Override
    public int compare(Object o1, Object o2) {
        Student s1 = (Student) o1;
        Student s2 = (Student) o2;
        return s1.getAge()-s2.getAge();
    }
}

你可能感兴趣的:(Java应用,Java基础,java)