一、概念
二、内置函数式接口
- Supplier接口
生产一个数据
- Consumer接口
是消费一个数据
- Function接口
java.util.function.Function<T,R> 根据一个类型的数据得到另一个类型的数据
- Predicate接口
对某种类型的数据进行判断,从而得到一个boolean值结果
三、获取Stream流方式
1、通过Collection
1.1 Collection
ArrayList()
ArrayList<String> arrayList = new ArrayList<>(); arrayList.stream().forEach(System.out::println);
HashSet()
HashSet<String> hashSet = new HashSet<>(); hashSet.stream().forEach(System.out::println);
1.2 Map
先获取key/value的集合,再遍历
HashMap<String, String> hashMap = new HashMap<>(); hashMap.entrySet().stream().forEach(System.out::println);
2、静态方法
Stream<String>stram = Stream.of("aa","bb","cc");
基本数据类型
会将整个数组,当成一个元素,进行处理
// 注意:基本数据类型的数组不行 int[] arr3 = {11, 22, 33}; Stream<int[]> stream9 = Stream.of(arr3);
四、常用方法
1、函数拼接方法
1.1 forEach
用来遍历流中的数据
特点
- 逐一处理
- 返回:void
- 种类:终结
// 带参数类型 one.stream().forEach((String s) -> { System.out.println(s); }); // 可带处理逻辑方式 one.stream().forEach(s -> System.out.println(s)); // 简化版 one.stream().forEach(System.out::println);
其它API
// 以流内具有顺序进行循环(先将并行流合并后,按内部排序,再进行循环) stream.forEachOrdered(System.out::println);
1.2 filter
于过滤数据,返回符合过滤条件的数据
特点
- 过滤
- 返回:Stream
- 种类:函数拼接
one.stream() .filter(s -> s.length() == 2) .forEach(System.out::println);
1.3 limit
对流进行截取,只取用前n个
特点
- 取用前几个
- 返回:Stream
- 种类:函数拼接
one.stream().limit(3); one.stream() .limit(3) .forEach(System.out::println);
1.4 skip
跳过前几个元素,可以使用 skip 方法获取一个截取之后的新流:
特点
- 跳过前几个
- 返回:Stream
- 种类:函数拼接
one.stream().skip(3); one.stream() .skip(3) .forEach(System.out::println);
1.5 map
将流中的元素映射到另一个流中
特点
- 映射
- 返回:Stream
- 种类:函数拼接
one.stream().map(Integer::parseInt); one.stream().map(Integer::parseInt).forEach(System.out::println); one.stream() .map(s->Integer.parseInt(s));
其它API:
// 返回为Double流 .mapToDouble(c -> 1.0) // 返回为Long流 .mapToLong(b -> 1L) // 返回为Int流 .mapToInt(a -> 3)
1.6 flatMap
扁平化流处理
也就是将单个流,再进行条件筛选。1个流,分成2个流,或者0个流。
Stream<String> lines = Arrays.stream("18 +7,8,9".split(",")); // ["18","+7","8","9"] List<String> collect3 = lines .flatMap(line -> Stream.of(line.split(" +"))) .collect(Collectors.toList()); // [] List<Object> collect4 = lines .flatMap(s -> null) .collect(Collectors.toList());
其它的API
// 返回为Double流 .flatMapToDouble(c -> DoubleStream.of(1.0)) // 返回为Int流 .flatMapToInt(b -> IntStream.of(1)) // 返回为Long流 .flatMapToLong(a-> LongStream.of(2L))
1.7 sorted
将数据进行排序(自然/比较器)
特点
- 组合
- 返回:Stream
- 种类:函数拼接
// 自然排序 one.stream().sorted().forEach(System.out::println); // 自定义排序(升序) one.stream().map(Integer::parseInt).sorted((o1,o2)-> o1-o2); // 自定义排序(降序) one.stream().map(Integer::parseInt).sorted((o1,o2)-> o2-o1);
1.8 distinct
去除重复数据
- 组合
- 返回:Stream
- 种类:函数拼接
// 基本 strings.stream().distinct().forEach(System.out::println);
根据实体类字段
实体类
class Person{ private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } }
代码
Stream.of( new Person("张三",10), new Person("李四",11), new Person("王五",12) ).distinct().forEach(System.out::println);
1.9 ***match
有3个相应API
// 元素是否全部满足条件 allMatch // 元素是否任意有一个满足条件 anyMatch // 元素是否全部不满足条件 noneMatch
案例:
// allMatch:元素是否全部满足条件 boolean result01 = one.stream().allMatch(a -> a.length() == 3); // anyMatch:元素是否任意有一个满足条件 boolean result02 = one.stream().anyMatch(d -> d.length() == 3); // noneMatch:元素是否全部不满足条件 boolean result03 = one.stream().noneMatch(c -> c.length() == 3);
1.10 find***
查找某些条件元素
内有2个API构成。结果为Option,依据Option语法执行
// 查找首个元素 findFirst() // 查找任一元素 findAny()
案例:
// 查找首个元素(findFirst()) Optional<String> first = one.stream().findFirst(); System.out.println("first="+first.get()); // 查找任一元素(findAny()) Optional<String> any1 = one.stream().findAny(); System.out.println(any1.get());
1.11 max/min
获取最大值/最小值
// 最大值(max) Optional<Integer> max = ints.stream().max((o1, o2) -> o1 - o2 ints.stream().max(Comparator.comparingInt(o -> o)); System.out.println("max: " + max.get()); // 最小值(min) Optional<Integer> min = ints.stream().min((o1, o2) -> o1 - o2); System.out.println("minx: " + min.get());
1.12 reduce
将所有数据归纳到一个数据
原理
- 第一次将默认赋值为x,取第一个值给y,进行操作。
- 第二次将第一次结果赋值给x,取第二个值给y,进行操作。
// 简单归纳 Integer reduce1 = one.stream().reduce(0, (a, b) -> a + b); Integer reduce2 = one.stream().reduce(0, (c, d) -> Integer.sum(c, d)); Integer reduce3 = one.stream().reduce(0, Integer::sum); // 自定义 Integer reduce = one.stream() .reduce(0, (x, y) -> { return x + y; });
1.13 concat
将2个流合并成1个流
Stream<String> stream01 = Stream.of("张三"); Stream<String> stream02 = Stream.of("李四"); Stream.concat(stream01, stream02).forEach(System.out::println);
2、终结方法
2.1 计数(count)
统计其中的元素个数
特点:
- 统计个数。
- 返回:long。
- 种类:终结。
one.stream().count()
2.2 输出打印(sout)
one.stream().forEach(System.out::println);
3、结果收集
3.1 收集到集合中(collect)
收集到List中
// 收集到List集合中 List<String> collect = Stream.of("aa", "bb", "cc").collect(Collectors.toList());
收集到Set中
// 收集到Set集合中 Set<String> set = Stream.of("aa", "bb", "cc").collect(Collectors.toSet());
收集到ArrayList中
// 收集到ArrayList中 ArrayList<String> arrayList = Stream.of("aa", "bb", "cc").collect(Collectors.toCollection(ArrayList::new)); String[] split = "1,23,456,7890".split(","); ArrayList<Object> collect1 = Arrays.stream(split).collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
收集到HashSet中
// 收集到HashSet中 HashSet<String> hashSet = Stream.of("aa", "bb", "cc").collect(Collectors.toCollection(HashSet::new));
3.2 收集到数组中(toArray)
核心API:object[] Array();
Object[] objectArray = Stream.of("aa", "bb", "cc").toArray(); // 带类型 String[] strings = Stream.of("aa", "bb", "cc").toArray(String[]::new); User[] users = Arrays.stream(split).toArray(User[]::new);
3.3 收集到字符串中(collect)
String[] split = "1,23,456,7890".split(","); StringBuilder collect = Arrays.stream(split).collect(StringBuilder::new, StringBuilder::append, StringBuilder::append);
4、Collectors中的方法
4.1 最大值
// 获取最大值 one.stream().collect(Collectors.maxBy((o1, o2) -> o1 - o2));
4.2 最小值
// 获取最小值 one.stream().collect(Collectors.minBy((o1, o2) -> o1 - o2));
4.3 求总和
// 求总和 one.stream().collect(Collectors.summingInt(Integer::intValue));
4.4 平均值
// 平均值 one.stream().collect(Collectors.averagingInt(Integer::intValue));
4.5 统计数量
// 统计数量 one.stream().collect(Collectors.counting());
4.6 进行单级分组(groupingBy)
根据某个字段分组
Map<Integer, List<Person>> listMap = Stream.of( new Person("张三", 10), new Person("李四", 11), new Person("王五", 12) ).collect(Collectors.groupingBy(Person::getAge));
自定义分组
实体类:
static class Person { private String name; private int age; }
代码:
Map<String, List<Person>> map = Stream.of( new Person("张三", 10), new Person("李四", 11), new Person("王五", 12) ).collect(Collectors.groupingBy((s) -> { if (s.getAge() > 10) { return "满足"; } else { return "不满足"; } })); map.forEach((k,v)->{ System.out.println(k+":"+v); });
结果:
不满足:[Person{name='张三', age=10}] 满足:[Person{name='李四', age=11}, Person{name='王五', age=12}]
4.7 进行多级分组
实体类:
static class Person { private String name; private int age; private int socre; }
代码:
Map<Integer, Map<String, List<Person>>> mapMap = Stream.of( new Person("张三", 10, 60), new Person("李四", 11, 80), new Person("王五", 12, 99) ).collect(Collectors.groupingBy(s -> s.getAge(), Collectors.groupingBy(s -> { if (s.getAge() > 10 && s.getSocre() > 60) { return "及格"; } else if (s.getAge() < 10 && s.getSocre() < 60) { return "良好"; } else { return "不及格"; } }))); mapMap.forEach((k, v) -> { System.out.println(k + "==:" + v); });
结果:
10==:{不及格=[Person{name='张三', age=10, socre=60}]} 11==:{及格=[Person{name='李四', age=11, socre=80}]} 12==:{及格=[Person{name='王五', age=12, socre=99}]}
4.8 进行分区
实体类
static class Person { private String name; private int age; private int socre; }
代码:
Stream<Person> stream = Stream.of( new Person("张三", 10, 60), new Person("李四", 11, 80), new Person("王五", 12, 99) ); Map<Boolean, List<Person>> map01 = stream.collect(Collectors.partitioningBy(s -> s.getSocre() > 90)); map01.forEach((k, v) -> { System.out.println(k + "==:" + v); });
结果:
false==:[Person{name='张三', age=10, socre=60}, Person{name='李四', age=11, socre=80}] true==:[Person{name='王五', age=12, socre=99}]
4.9 进行拼接
为多个内容之间,插入数据。
// B张三A李四A王五C String collect1 = stream02.map(Person::getName).collect(Collectors.joining("A", "B", "C"));
五、全部方法
- peek
改变Object中值,不改变String中值,与map类似
六、Optional
1、Optional.of()
赋值(初始化)
System.out.println("=======1、为空判断"); Optional<String> name = Optional.of("name"); System.out.println(name.isPresent()); //true
2、isPresent()
是否为空判断
System.out.println("=======2、isPresent()是否为空判断"); boolean name1 = Optional.ofNullable("name").filter(s -> "name".equals(s)).isPresent(); //true System.out.println(name1);
3、.ifPresent()
不为空时操作
stream.findAny().ifPresent(System.out::println);
4、Optional.ofNullable(“ff”);
获取Optional(无:返回空Optional。有值:返回Option)
Optional<String> s = Optional.ofNullable("");
5、.get( )
获取值
Optional<String> ff = Optional.of("ff"); System.out.println(ff.get());
6、orElse()
为空时,赋值指定字符串
System.out.println("=======3、orElse: 为空时,取指字符串"); System.out.println(Optional.ofNullable(null).orElse("张三")); //张三
String result = Optional.ofNullable("ddd") .map(s -> "不为空执行业务流程。") .orElse("为空返回false");
// 为空,返回null对象 User user = userList.stream() .findFirst() .orElse(null);
7、orElseGet()
orElseGet: 为空时,取类中值
System.out.println("=======4、orElseGet: 为空时,取类中值"); StartConfig startConfig = new StartConfig(); startConfig.setTest01("test01"); System.out.println(Optional.ofNullable(null).orElseGet(startConfig::getTest01)); //test01
8、Optional.empty();
返回一个空的Optional
Optional<Object> empty = Optional.empty();
七、其它
1、注意事项
- Stream只能操作一次。
- Stream方法返回的是新的流。
- Stream不调用终结方法,中间的操作不会执行。
2、参考地址
https://www.runoob.com/java/java8-streams.html
https://www.runoob.com/java/java8-streams.html
八、Xmind
https://download.csdn.net/download/weixin_44624117/87670715