说明
stream 操作的数据源为:集合、数组 。流讲的是计算
1. stream 自己不会在存储元素
2. stream 不会改变源对象。相反他们会返回一个持有结果的新stream
3. stream 操作是延时执行的。这意味丰他们会等到需要结果的时候才执行
流的创建
//1 .通过 collection 集合提供的 stream()【串行】 和 parallelStream()【并行】
List<String> list = new ArrayList<>();
list.stream();
//2. 通过 Arrays 中静态方法 stream() 获取数组流
Arrays.stream("a,b,c".split(","));
//3. 通过Stream 类中的静态方法 of
Stream.of("a", "b", "c");
//4. 创建无限流
Stream.iterate(0,(x) -> x+2);
Stream.generate(Math::random);
中间操作 (不会生成任何结果)
1. 筛选
filter : 过滤
limit : 截取
skip :获取前 N个元素
distinct :去重
只选择 >0.5的随机数。只获取10个,跳过前3个元素,排除相同的元素
Stream.generate(Math::random)
.filter((x) -> x > 0.5)
.limit(10)
.skip(3)
.distinct();
2. 映射 (map)
将 double 转成 int 类型
Stream.generate(Math::random)
.map((x) -> (int) (x * 100)).limit(10)
.forEach(System.out::println);
flatMap 将流中的每一个值都换成另一个流,把所有的流都连接成一个流
3.排序 (sorted)
Stream.generate(Math::random)
.sorted() ;
list.stream()
.sorted(Comparator.comparing(Apple::getName))
.collect(Collectors.toList());
终止操作
stream 【终止操作】才会生成结果,【中间操作】不会
- 1. 匹配 - 集合中的元素是否表达示匹配,返回 boolean
anyMatch : 至少匹配一个元素
allMatch : 匹配所有元素
noneMatch:没有匹配所有元素
- 2. 查找 -对元素进行查找
findFirst :获取第一个元素
findAny :获取任意元素
count :获取元素数量
max :获取元素中的最大值
min:获取元素中的最小值
- 3. 归约 reduce - 可以将流中元素反复结合起来,得到一个值。
将 1,2,3,4,5 累加起来
int total = Stream.of(1, 2, 3, 4, 5)
.reduce(0, (x, y) -> x + y);
Optional<Integer> total = Stream.of(1, 2, 3, 4, 5)
.reduce(Integer::sum);
- 4. 收集 将stream 中的元素收集成一个集合
List<Integer> code = Stream.of("Mary", "Jack", "Water", "Amy", "Jame")
.map(String::hashCode)
.collect(Collectors.toList());
//放在 ArrayList中
List<Integer> code = Stream.of("Mary", "Jack", "Water", "Amy", "Jame")
.map(String::hashCode)
.collect(Collectors.toCollection(ArrayList::new));
Collectors.groupingBy(); //分组
Collectors.maxBy(); //最大值
Collectors.minBy(); //最小值
Collectors.toCollection(); //生成指定集合
Collectors.toList(); //生成list
Collectors.toSet(); //生成set
Collectors.counting(); //元素个数
Collectors.joining(); //字符串连接
Collectors.partitioningBy(); //分区
Collectors.summingInt(); //求和
Collectors.toMap(); //
Collectors.summarizingInt();//
Collectors.reducing();
Collectors.mapping();
案例
list.stream().map(Apple::getName)
.filter(Objects::nonNull) //选择不为null的Apple
.distinct() //不能重复
.skip(1) //跳过第1个
.limit(3) //最多返回3个
.sorted(String::compareTo) //排序
.peek(System.out::println) //打印结果
.collect(Collectors.toList()); //收集结果
//流的扁平化
//找出下面单词所组成的字母
Arrays.asList("apple","tomato","peak").stream()
.map(item->item.split("")) //返回 字符数组
.flatMap(Arrays::stream) //将 字符数组转成流,再将流合并
.distinct() //去重
.collect(Collectors.toList()); //收集结果
//数值流 及 元素求和
// 有拆箱的操作
Optional<Integer> A = Stream.of(1, 2, 3, 4).reduce(Integer::sum);
Integer B = Stream.of(1, 2, 3, 4).reduce(0, Integer::sum);
LongStream.of(1, 2, 3, 4).boxed().reduce(Long::sum);//将原始类型转成包装类型
// 无拆箱操作
IntStream.of(1, 2, 3, 4).sum();
Stream.of(1, 2, 3, 4).mapToInt(x -> x).sum(); //将包装类型转原始类型
//数值范围
LongStream.rangeClosed(1, 100).close(); // 1-100 包含100
IntStream.range(1,100).close(); //1-100 不包含100
//从 打开 data.txt 文件,并各行读取内容。
try (Stream<String> lines = Files.lines(Paths.get("data.txt"), Charset.defaultCharset())) {
//在try()打开的文件,流会自动关闭,不用写finally 去关闭流
lines.peek(System.out::println)
.close();
} catch (IOException e) {
//如果打开文件时出现出现异常则加以处理
}
//Collectors 使用
//收集
new ArrayList<Apple>().stream().collect(Collectors.toList()); //收集至list中
new ArrayList<Apple>().stream().collect(Collectors.toSet()); //收集至set中
new ArrayList<Apple>().stream().collect(Collectors.toCollection(HashSet::new));//自定义收集器
Map<String, Apple> map1 = new ArrayList<Apple>().stream() //收集至map中
.collect(Collectors.toMap(Apple::getName, Function.identity()));
Map<String, Integer> map2 = new ArrayList<Apple>().stream() //收集至map中
.collect(Collectors.toMap(Apple::getName, Apple::getWeight));
//数值计算
Stream.of(1, 2, 3, 4).collect(Collectors.summingInt(x -> x)); //求和
Stream.of(1, 2, 3, 4).collect(Collectors.averagingInt(x -> x)); //平均值
Stream.of(1, 2, 3, 4).collect(Collectors.maxBy(Integer::compare)); //最大值
Stream.of(1, 2, 3, 4).collect(Collectors.minBy(Integer::compare)); //最小值
Stream.of(1, 2, 3, 4).collect(Collectors.counting()); //个数
IntSummaryStatistics stat = Stream.of(1, 2, 3, 4).collect(Collectors.summarizingInt(x -> x));
stat.getSum(); //求和
stat.getAverage(); //平均值
stat.getMax(); //最大值
stat.getMin(); //最小值
stat.getCount(); //个数
//字符串连接
Stream.of("a", "b", "c").collect(Collectors.joining()); //abc
Stream.of("a", "b", "c").collect(Collectors.joining(","));//a,b,c
Stream.of("a", "b", "c").collect(Collectors.joining(",", "[", "]"));//[a,b,c]
//归约
Integer sum = Stream.of(1, 2, 3, 4).collect(Collectors.reducing(0, Integer::sum)); //利用归约来求和
Optional<Integer> sumOptional = Stream.of(1, 2, 3, 4).collect(Collectors.reducing(Integer::sum)); //利用归约来求和
new ArrayList<Apple>().stream()
.collect(Collectors.reducing(0, Apple::getWeight, Integer::sum)); //对苹果的重量进行求和
//collectingAndThen 把收集器返回的结果转换为另一种类型
//将找出最重的苹果,返回 Apple对象,而不是 Optional<Application>
Collectors.collectingAndThen(Collectors.maxBy(Comparator.comparingInt(Apple::getWeight)), Optional::get);
// mapping 第一个参数表示变化,第二个参数表示收集
//获取每个苹果的重量,并将其收集成set
Collectors.mapping(Apple::getWeight, Collectors.toSet());
//分组
Map<Integer, List<Apple>> group1 =
new ArrayList<Apple>().stream() //根据苹果的重量进行分组
.collect(Collectors.groupingBy(Apple::getWeight));
Map<Integer, Map<String, List<Apple>>> group2 =
new ArrayList<Apple>().stream() //根据苹果的重量和名称分组
.collect(Collectors.groupingBy(Apple::getWeight,
Collectors.groupingBy(Apple::getName)));
Map<String, Integer> group3 =
new ArrayList<Apple>().stream() //根据苹果的名称分组,计算每组苹果重量的和
.collect(Collectors.groupingBy(Apple::getName,
Collectors.summingInt(Apple::getWeight)));
Map<String, Optional<Apple>> group4 =
new ArrayList<Apple>().stream() //根据苹果的名称分组,找出最重的苹果
.collect(Collectors.groupingBy(Apple::getName,
Collectors.maxBy(Comparator.comparingInt(Apple::getWeight))));
Map<String, Apple> group5 =
new ArrayList<Apple>().stream() //根据苹果的名称分组,找出最重的苹果
.collect(Collectors.groupingBy(Apple::getName,
Collectors.collectingAndThen(
Collectors.maxBy(Comparator.comparingInt(Apple::getWeight)), Optional::get)));
Map<String, Set<Integer>> group6 =
new ArrayList<Apple>().stream() //根据苹果的名称分组, 获取每组苹果的重量收集成set
.collect(Collectors.groupingBy(Apple::getName,
Collectors.mapping(Apple::getWeight, Collectors.toSet())));
//分区
Map<Boolean, List<Apple>> group7 =
new ArrayList<Apple>().stream() //根据苹果的重量分组,条件 weight>5
.collect(Collectors.partitioningBy(apple -> apple.getWeight() > 5));
this.diffItems.stream() //分组后再计算每组的数量
.collect(Collectors.groupingBy(TradeDiffItem::getDiffType, Collectors.counting()));
Map<String, Apple> group9 =
new ArrayList<Apple>().stream() //根据苹果的名称分组,找出每组中第一个元素
.collect(Collectors.groupingBy(Apple::getName,
Collectors.collectingAndThen(Collectors.toList(),
item-> item.get(0)
));