一、概念
二、内置函数式接口
- Supplier接口
生产一个数据
- Consumer接口
是消费一个数据
- Function接口
java.util.function.Function<T,R>
根据一个类型的数据得到另一个类型的数据
- Predicate接口
对某种类型的数据进行判断,从而得到一个boolean值结果
三、获取Stream流方式
1、通过Collection
1.1 Collection
ArrayList()
代码语言:javascript复制ArrayList<String> arrayList = new ArrayList<>();
arrayList.stream().forEach(System.out::println);
HashSet()
代码语言:javascript复制HashSet<String> hashSet = new HashSet<>();
hashSet.stream().forEach(System.out::println);
1.2 Map
先获取key/value的集合,再遍历
代码语言:javascript复制HashMap<String, String> hashMap = new HashMap<>();
hashMap.entrySet().stream().forEach(System.out::println);
2、静态方法
代码语言:javascript复制Stream<String>stram = Stream.of("aa","bb","cc");
基本数据类型
会将整个数组,当成一个元素,进行处理
代码语言:javascript复制// 注意:基本数据类型的数组不行
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
代码语言:javascript复制// 以流内具有顺序进行循环(先将并行流合并后,按内部排序,再进行循环)
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:
代码语言:javascript复制// 返回为Double流
.mapToDouble(c -> 1.0)
// 返回为Long流
.mapToLong(b -> 1L)
// 返回为Int流
.mapToInt(a -> 3)
1.6 flatMap
扁平化流处理
也就是将单个流,再进行条件筛选。1个流,分成2个流,或者0个流。
代码语言:javascript复制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
代码语言:javascript复制// 返回为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);
根据实体类字段
实体类
代码语言:javascript复制class Person{
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
代码
代码语言:javascript复制Stream.of(
new Person("张三",10),
new Person("李四",11),
new Person("王五",12)
).distinct().forEach(System.out::println);
1.9 ***match
有3个相应API
代码语言:javascript复制// 元素是否全部满足条件
allMatch
// 元素是否任意有一个满足条件
anyMatch
// 元素是否全部不满足条件
noneMatch
案例:
代码语言:javascript复制// 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语法执行
代码语言:javascript复制// 查找首个元素
findFirst()
// 查找任一元素
findAny()
案例:
代码语言:javascript复制// 查找首个元素(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
获取最大值/最小值
代码语言:javascript复制// 最大值(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个流
代码语言:javascript复制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)
代码语言:javascript复制one.stream().forEach(System.out::println);
3、结果收集
3.1 收集到集合中(collect)
收集到List中
代码语言:javascript复制// 收集到List集合中
List<String> collect = Stream.of("aa", "bb", "cc").collect(Collectors.toList());
收集到Set中
代码语言:javascript复制// 收集到Set集合中
Set<String> set = Stream.of("aa", "bb", "cc").collect(Collectors.toSet());
收集到ArrayList中
代码语言:javascript复制// 收集到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中
代码语言:javascript复制// 收集到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)
代码语言:javascript复制String[] split = "1,23,456,7890".split(",");
StringBuilder collect = Arrays.stream(split).collect(StringBuilder::new, StringBuilder::append, StringBuilder::append);
4、Collectors中的方法
4.1 最大值
代码语言:javascript复制// 获取最大值
one.stream().collect(Collectors.maxBy((o1, o2) -> o1 - o2));
4.2 最小值
代码语言:javascript复制// 获取最小值
one.stream().collect(Collectors.minBy((o1, o2) -> o1 - o2));
4.3 求总和
代码语言:javascript复制// 求总和
one.stream().collect(Collectors.summingInt(Integer::intValue));
4.4 平均值
代码语言:javascript复制// 平均值
one.stream().collect(Collectors.averagingInt(Integer::intValue));
4.5 统计数量
代码语言:javascript复制// 统计数量
one.stream().collect(Collectors.counting());
4.6 进行单级分组(groupingBy)
根据某个字段分组
代码语言:javascript复制Map<Integer, List<Person>> listMap = Stream.of(
new Person("张三", 10),
new Person("李四", 11),
new Person("王五", 12)
).collect(Collectors.groupingBy(Person::getAge));
自定义分组
实体类:
代码语言:javascript复制static class Person {
private String name;
private int age;
}
代码:
代码语言:javascript复制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);
});
结果:
代码语言:javascript复制不满足:[Person{name='张三', age=10}]
满足:[Person{name='李四', age=11}, Person{name='王五', age=12}]
4.7 进行多级分组
实体类:
代码语言:javascript复制static class Person {
private String name;
private int age;
private int socre;
}
代码:
代码语言:javascript复制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);
});
结果:
代码语言:javascript复制10==:{不及格=[Person{name='张三', age=10, socre=60}]}
11==:{及格=[Person{name='李四', age=11, socre=80}]}
12==:{及格=[Person{name='王五', age=12, socre=99}]}
4.8 进行分区
实体类
代码语言:javascript复制static class Person {
private String name;
private int age;
private int socre;
}
代码:
代码语言:javascript复制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);
});
结果:
代码语言:javascript复制false==:[Person{name='张三', age=10, socre=60}, Person{name='李四', age=11, socre=80}]
true==:[Person{name='王五', age=12, socre=99}]
4.9 进行拼接
为多个内容之间,插入数据。
代码语言:javascript复制// B张三A李四A王五C
String collect1 = stream02.map(Person::getName).collect(Collectors.joining("A", "B", "C"));
五、全部方法
- peek
改变Object中值,不改变String中值,与map类似
六、Optional
1、Optional.of()
赋值(初始化)
代码语言:javascript复制System.out.println("=======1、为空判断");
Optional<String> name = Optional.of("name");
System.out.println(name.isPresent()); //true
2、isPresent()
是否为空判断
代码语言:javascript复制System.out.println("=======2、isPresent()是否为空判断");
boolean name1 = Optional.ofNullable("name").filter(s -> "name".equals(s)).isPresent(); //true
System.out.println(name1);
3、.ifPresent()
不为空时操作
代码语言:javascript复制stream.findAny().ifPresent(System.out::println);
4、Optional.ofNullable(“ff”);
获取Optional(无:返回空Optional。有值:返回Option)
代码语言:javascript复制Optional<String> s = Optional.ofNullable("");
5、.get( )
获取值
代码语言:javascript复制Optional<String> ff = Optional.of("ff");
System.out.println(ff.get());
6、orElse()
为空时,赋值指定字符串
代码语言:javascript复制System.out.println("=======3、orElse: 为空时,取指字符串");
System.out.println(Optional.ofNullable(null).orElse("张三")); //张三
代码语言:javascript复制String result = Optional.ofNullable("ddd")
.map(s -> "不为空执行业务流程。")
.orElse("为空返回false");
代码语言:javascript复制// 为空,返回null对象
User user = userList.stream()
.findFirst()
.orElse(null);
7、orElseGet()
orElseGet: 为空时,取类中值
代码语言:javascript复制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
代码语言:javascript复制Optional<Object> empty = Optional.empty();
七、其它
1、注意事项
- Stream只能操作一次。
- Stream方法返回的是新的流。
- Stream不调用终结方法,中间的操作不会执行。
2、参考地址
https://www.runoob.com/java/java8-streams.html
代码语言:javascript复制https://www.runoob.com/java/java8-streams.html
八、Xmind
CSDN
代码语言:javascript复制https://download.csdn.net/download/weixin_44624117/87670715