目录
Stream流的概念
Stream流 :
- Stream是JDK1.8中处理集合的关键抽象概念
- 使用Stream API对集合进行操作
- Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。
这样处理元素集合可以看作一种“流”,流在管道里运输,可以在管道节点进行处理:
特点 :
- 不是数据结构,不会保存数据,只会操作数据
- 数据源,流的来源可以是集合,数组,I/O channel,产生器generator 等。
- 聚合操作 类似SQL语句一样的操作。
- 不会改变数据源,它会将操作后的数据保存到另外一个对象中。
- 延迟执行。
Stream流式操作步骤:
-
先得到集合或者数组的Stream流(就是一根传送带)
-
把元素放上去
-
然后就用这个Stream流简化的API来方便的操作元素
Stream流的三类方法:
1.获取Stream流
创建Stream,并把数据放到流水线上准备进行操作
2.中间方法
流的操作链。一次操作完毕之后,还可以继续进行其他操作
3.终结方法
一个Stream流只能有一个终结方法,执行终止操作,流无法再使用
获取Stream流
1.生成Stream流
在 Java 8 中, 集合接口有两个方法来生成流:
- stream() − 为集合创建串行流
- parallelStream() − 为集合创建并行流
2.获取Stream流的方式
所有的 Collection 集合都可以通过 .stream() 方法来获取流:
数组获取流:
获取流的方式:
import java.util.*;
import java.util.stream.IntStream;
import java.util.stream.Stream;
/**
获取 Stream流的方式
*/
public class GetStreamDemo {
public static void main(String[] args) {
//Collection获取流
//Collection接口中有一个默认的方法:default Stream<E> stream()
//1.List获取流
List<String> list = new ArrayList<>();
Stream<String> stream01 = list.stream();
//2.Set获取流
Set<String> set = new HashSet<>();
Stream<String> stream02 = set.stream();
//3.Map获取流
//Map 并没有继承自 Collection 接口,所有无法通过该 map.stream()获取流。但是可用通过如下三种方式获取:
Map<String,String> map = new HashMap<>();
Stream<String> stream03 = map.keySet().stream();
Stream<String> stream04 = map.values().stream();
Stream<Map.Entry<String, String>> stream05 = map.entrySet().stream();
//数组获取流
// static<T> Stream<T> of(T... values)
// T... values:可变参数,实际原理就是可变数组(传递String数组进去)
//1.字符串获取流
Stream<String> stream06 = Stream.of("aa", "bb", "cc");
//2.数组类型(基本类型除外)
String[] strs = {"aa","bb","cc"};
Stream<String> stream07 = Stream.of(strs);
//3.基本数据类型的数组
int[] arr = {1,2,3,4};
//看着没报错,但是看到返回值是 int[],这是 Stream流把整个数组看做一个元素来操作,而不是操作数组中的int元素(这样子是不行的!!!)
Stream<int[]> stream08 = Stream.of(arr);
// 使用Arrays.stream(T[] array)方法
Integer[] arr1={1,2,3,5,6};
Stream<Integer> stream09 = Arrays.stream(arr1);
//数值基本类型数组得到对应的流
IntStream stream10 = Arrays.stream(arr);
}
}
常见的StreamAPI操作
1.过滤筛选
- filter: 过滤流中的元素,返回一个Stream Stream<T> filter(Predicate<? super T> predicate)
- limit(n):获取前n个元素 Stream<T> limit(long maxSize);
- skip(n):跳过n元素,配合limit(n)可实现分页 Stream<T> skip(long n);
- distinct:通过流中元素的 hashCode() 和 equals() 去除重复元素 Stream<T> distinct();
public class testStreamfilter {
/**
* list集合stream流式操作
*/
@Test
public void testStreamList() {
List<String> list = new ArrayList<>();
list.add("狂徒张三");
list.add("李四李");
list.add("王五");
list.add("老六")
list.add("孙七");
list.add("赵八");
list.stream().filter(e -> e.startsWith("张")) //过滤所有姓张的人
.filter(e -> e.length() == 3) //过滤所有姓名是3个字的人
//遍历打印,System.out::println表明 System.out调用println打印方法
.forEach(System.out::println);
}
/**
* limit 方法 ,返回前n个元素数据值组成的Stream。
*/
@Test
public void testLimit() {
List<String> list = new ArrayList<>();
list.add("狂徒张三");
list.add("李四李");
list.add("王五");
list.add("老六")
list.add("孙七");
list.add("赵八");
list.stream().limit(3).forEach(System.out::println); //取前3个
}
/**
* skip方法 ,跳过前n个元素的中间流操作,返回剩下的值。
*/
@Test
public void testSkip() {
List<String> list = new ArrayList<>();
list.add("狂徒张三");
list.add("李四李");
list.add("王五");
list.add("老六")
list.add("孙七");
list.add("赵八");
//list.stream().skip(3).forEach(System.out::println); //跳过前3个
list.stream().skip(3).limit(2).forEach(System.out::println); //skip+limit实现分页
}
/**
* distinct, 返回去重的Stream
*/
@Test
public void testDistinct() {
List<String> list = new ArrayList<>();
list.add("狂徒张三");
list.add("李四李");
list.add("王五");
list.add("王五");
list.add("老六")
list.add("孙七");
list.add("孙七");
list.add("赵八");
list.stream().distinct().forEach(System.out::println);
}
}
2.映射
- map:接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。<R> Stream<R> map(Function<? super T, ? extends R> mapper);
- forEach:ForEach流式遍历集合 void forEach(Consumer<? super T> action);
public class testStreamMapping {
/**
* 遍历map集合,截取substring(2)开始的值
*/
@Test
public void testMap() {
List<String> list = new ArrayList<>();
list.add("狂徒张三");
list.add("李四四");
list.add("王五");
list.add("老六")
list.add("孙七");
list.add("赵八");
Stream<String> stream = list.stream().map(e -> e.substring(2));
stream.forEach(System.out::println);
}
/**
* forEach, ForEach流式遍历list集合
*/
@Test
public void testForEach() {
List<String> list = new ArrayList<>();
list.add("狂徒张三");
list.add("李四四");
list.add("王五");
list.add("老六")
list.add("孙七");
list.add("赵八");
list.stream().forEach(System.out::println);
}
}
还有好多Stream流的操作,收集流,count,以及操作方法组合使用等.