Java,Stream API的使用

Stream是数据渠道,用于操作数据源(集合、数组等)所生成的元素序列。

Stream和Collection集合的区别:Collection是一种静态的内存数据结构,讲的是数据,而Stream是有关计算的,讲的是计算。集合主要面向内存,储存在内存中。Stream主要面向CPU,通过CPU实现计算。

Stream API关注的是多个数据的计算(排序、查找、过滤、映射、遍历等)。

集合关注的是数据的存储。

说明:

  • Stream自己不会存储元素。

  • Stream不会改变源对象,而是会返回一个持有结果的新的Stream。

  • Stream操作是延迟执行的。要等到需要的结果的时候才执行。一旦执行终止操作,就执行中间操作,并产生结果。

  • Stream一旦执行了终止操作,就不能再调用其他中间操作或终止操作了。

Stream执行流程:

步骤一:Stream的实例化

    ·创建Stream方式一:通过集合。

List list = new ArrayList<>();
list.add(new Person(19,"limingmao"));
list.add(new Person(17,"qiuqiuren"));
list.add(new Person(18,"pianpianhua"));
//default Stream Stream():返回一个顺序流
Stream stream = list.stream();
//default Stream Stream():返回一个并行流
Stream stream1 = list.parallelStream();

    ·创建Stream方式二:通过数组。

//调用Arrays类的static  Stream stream(T[] array):返回一个流
Integer[] arr = new Integer[]{1,3,4,5,6,7,};
Stream stream = Arrays.stream(arr);
int[] arr1 = new int[]{1,2,3,4,5};
IntStream stream1 = Arrays.stream(arr1);

    ·创建Stream方式三:通过Stream的静态方法of( )。

//通过Stream的静态方法of()
Stream stringStream = Stream.of("aa", "bb", "cc", "DD");

步骤二:一系列的中间操作

  • 筛选与切片:

filter(Predicate p):接受lambda,从流中排除某些元素。

limit(n):截断流,使得元素不超过指定量。

skip(n):跳过元素,返回一个扔掉了前n个元素的流。若流中元素不足n个,则返回一个空流。

distinct( ):筛选,通过流所生成元素的hashCode( )和equals( )去除重复元素。

  • 映射

map(Function f):接收一个函数作为参数,将元素转换为其他形式或提取信息,该函数会被应用到每一个元素上。

操作,例:

List list = new ArrayList<>();
list.add("aa");
list.add("bb");
list.add("cc");
list.add("dd");
Stream stream = list.stream();
stream.map(str -> str.toUpperCase());
  • 排序

sorted( ):自然排序。要求类实现Comparable接口。

sorted(Comparator com):定制排序,参数传入实现Comparator接口的对象,指定排序方式。

步骤三:执行终止操作

终止操作会从流的流水线生成结果。其结果可以是任何不是流的值,例如,List、Integer,也可以是void。

流进行了终止操作后不能再次使用。

  • 匹配和查找:

allMatch(Predicate p):检查是否匹配所有元素。

anyMatch(Predicate p):检查是否至少匹配一个元素。

findFirst( ):返回第一个元素。

count( ):返回元素中的总个数。

max(Comparator c):返回流中的最大值。

min(Comparator c):返回流中的最小值。

forEach(Consumer c):内部迭代。

  • 归约:

reduce(T identity,BinaryOperator):可以将流中的元素反复结合起来,得到一个值。

reduce(BinaryOperator):可以将流中的元素反复结合起来,得到一个值。

  • 收集

collection(Collection c):将流转换为其他形式。接收一个Collection接口的实现,用于给Stream中元素做汇总的方法。

Stream中的Lambda表达式与方法引用的使用

Stream的使用中会用到较多的接口哦,使用Lambda表达式和方法引用的方式会更方便。

以两个例子为例

例一,比如:要打印出存放Person的对象的集合list里的对象的年龄的总和

System.out.println(list.stream().map(Person::getAge).reduce(Integer::sum));

map方法的参数中放的是一个Function的实现类对象,此时应用到每一个元素上的操作是调用每一个Person对象的getAge方法得到每一个对象的年龄,apply方法的参数是一个Person类的对象A,apply方法中,A调用了getAge方法,而getAge方法没有参数,满足方法n和n - 1的关系,可以使用方法引用的类 :: 实例方法 的方式表示,即为 Person :: getAge 。reduce方法中同理。

例二,比如:要打印所有大于十七岁的Person对象的信息

stream.filter(emp -> emp.getAge() > 17).forEach(System.out::println);

filter方法的参数中放的是一个Predicate的实现类对象,只有一个参数,所以->左边放一个变量,返回值是一个boolean类型的值,只有一条return语句,所以直接将return后面的emp.getAge( ) > 17放在->后面,便形成了lambda表达式。

forEach方法中放入的是一个Consumer的实现类对象,accept方法的返回值(类型推断后)与System.out对象调用的Println方法的返回值一致。便可以使用方法引用的方式,表示为System.out :: println 。

你可能感兴趣的:(java)