Stream 中⽂称为 “流”,通过将集合转换为这么⼀种叫做 “流”的元素队列,通过声明性⽅式,能够对集合中的每个元素进⾏⼀系列并⾏或串⾏的流⽔线操作
元素是特定类型的对象,所以元素集合看作⼀种流, 流在管道中传输, 且可以在管道的节点上进⾏处理, ⽐如 排序,聚合,过滤等操作
操作详情
数据元素便是原始集合,如list,set,map
生成流,可以使串行流stream或者并行流parallelStream
中间操作,可以使排序,聚合,过滤,转换等
终端操作,很多流操作本身就会返回一个流,所以多个操作可以直接连接起来,最后统一进行收集
开发前数据准备
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Long id;
private String name;
private Integer age;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserDTO {
private Long id;
private String name;
private Integer age;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Long id;
private String name;
private Integer age;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class VideoOrder {
private String tradeNo;
private String title;
private int money;
}
在日常开发中,对象转换是必不可少的,比如:mapper层实体类获取,到业务层转换为DTO,业务层到控制器AO等。
public static void testMap(){
List<User> list = Arrays.asList(
new User(1L, "张三", 18),
new User(2L, "李四", 20),
new User(3L, "王五", 33),
new User(4L, "赵六", 44));
List<UserDTO> userDTOList = list.stream().map(obj -> {
UserDTO userDTO = new UserDTO(obj.getId(), obj.getName(), obj.getAge());
return userDTO;
}).collect(Collectors.toList());
userDTOList.forEach(System.out::println);
}
有时候我们获取数据库的列表,有些数据不是我们想要的,这时候我们可以过滤掉不需要的数据。如下面示例过滤掉字符串长度大于7的字符串。
public static void testFilter(){
List<String> list = Arrays.asList(
"SpringBoot",
"SpringCloud",
"Spring",
"SpringMVC",
"mybatis",
"html",
"git"
);
List<String> stringList = list.stream().filter(obj -> obj.length() > 7).collect(Collectors.toList());
System.out.println(stringList);
}
sorted对流进行自然排序,其中的元素需要实现comparable接口 sorted(Comparatorcomparator)用于自定义升降序
public static void testSorted(){
List<String> list = Arrays.asList(
"SpringBoot",
"SpringCloud",
"Spring",
"SpringMVC",
"mybatis",
"html",
"git"
);
List<String> collect = list.stream().sorted().collect(Collectors.toList());
System.out.println(collect);
//根据长度进行排序
List<String> collect1 = list.stream().sorted(Comparator.comparing(String::length)).collect(Collectors.toList());
System.out.println(collect1);
//limit截取
List<String> collect2 = list.stream().sorted(Comparator.comparing(String::length).reversed()).limit(3).collect(Collectors.toList());
System.out.println(collect2);
}
allMatch检查是否匹配所有元素,符合才返回true
anyMatch检查是否至少匹配一个元素
示例:匹配列表中字符串长度大于5的数据,allMatch->false,anyMatch->true
public static void testAllOrAnyMatch(){
List<String> list = Arrays.asList(
"SpringBoot",
"SpringCloud",
"Spring",
"SpringMVC",
"mybatis",
"html",
"git"
);
boolean allMatch = list.stream().allMatch(obj -> obj.length() > 5);
System.out.println(allMatch);
boolean anyMatch = list.stream().anyMatch(obj -> obj.length() > 10);
System.out.println(anyMatch);
}
示例:求以下列表中年龄最大最小值
public static void testMaxMin(){
List<User> list = Arrays.asList(
new User(1L, "张三", 18),
new User(2L, "李四", 20),
new User(3L, "王五", 33),
new User(4L, "赵六", 44));
Optional<User> userOptional = list.stream().max(Comparator.comparingInt(User::getAge));
System.out.println(userOptional.get().getAge());
Optional<User> userOptional1 = list.stream().min(Comparator.comparingInt(User::getAge));
System.out.println(userOptional1.get().getAge());
}
reduce聚合操作,根据一定的规则将stream中的元素计算后返回一个唯一的值
常用方法 Optionalreduce(BinaryOperatoraccumulator)
常用方法二 T reduce(T identity,BinaryOperatoraccumulator)
示例:第一个元素与第二个元素累加在和第三个元素相加,直到全部加完
Integer value = Stream.of(1, 2, 3, 4, 5, 6).reduce((item1,item2) -> item1 + item2).get();
System.out.println(value);
//不适用lambda表达式
Integer value1 = Stream.of(1, 2, 3, 4, 5, 6).reduce(new BinaryOperator<Integer>() {
@Override
public Integer apply(Integer integer, Integer integer2)
{
return integer + integer2;
}
}).get();
//10作为初始值,然后和第一个数相加,结果再与第二个数相加,直到所有的数相加完成为止
Integer value3 = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9).reduce(10, (sum, item) -> sum + item);
示例:将"springBoot", “SpingMVC”, "mybatis"使用[]拼接
String collect = Stream.of("springBoot", "SpingMVC", "mybatis").collect(Collectors.joining(",", "[", "]"));
分组(partitionBy)
示例:将list中的数据进行分组,长度大于8的为一组,其他为另外一组
List<String> list = Arrays.asList(
"SpringBoot",
"SpringCloud",
"Spring",
"SpringMVC",
"mybatis",
"html",
"git"
);
Map<Boolean, List<String>> listMap = list.stream().collect(partitioningBy(obj -> obj.length() > 8));
listMap.forEach((key,value)->{
System.out.println(key);
value.forEach(System.out::println);
System.out.println();
});
根据学生的省份进行分组,并统计最大值、最小值、总人数、总和、平均值
//根据学生的省份进行分组
List<Student> students = Arrays.asList(new Student("⼴东", 23),
new Student("⼴东", 24),
new Student("⼴东", 23),
new Student("北京", 22),
new Student("北京", 20),
new Student("北京", 20),
new Student("海南", 25));
Map<String, List<Student>> collect = students.stream().collect(Collectors.groupingBy(obj -> obj.getProvince()));
collect.forEach((key,value)->{
System.out.println(key);
value.forEach(System.out::println);
});
//统计学生的各个年龄信息
IntSummaryStatistics summaryStatistics = students.stream().collect(Collectors.summarizingInt(Student::getAge));
System.out.println("平均值:"+summaryStatistics.getAverage());
System.out.println("人数:"+summaryStatistics.getCount());
System.out.println("最大值:"+summaryStatistics.getMax());
System.out.println("最小值:"+summaryStatistics.getMin());
System.out.println("总和:"+summaryStatistics.getSum());
public static void test1(){
//总价 35
List<VideoOrder> videoOrders1 = Arrays.asList(
new VideoOrder("20190242812", "springboot教程", 3),
new VideoOrder("20194350812", "微服务SpringCloud", 5),
new VideoOrder("20190814232", "Redis教程", 9),
new VideoOrder("20190523812", "⽹⻚开发教程", 9),
new VideoOrder("201932324", "百万并发实战Netty", 9));
//总价
List<VideoOrder> videoOrders2 = Arrays.asList(
new VideoOrder("2019024285312", "springboot教程", 3),
new VideoOrder("2019081453232", "Redis教程", 9),
new VideoOrder("20190522338312", "⽹⻚开发教程", 9),
new VideoOrder("2019435230812", "Jmeter压⼒测试", 5),
new VideoOrder("20193232411", "Git+Jenkins持续集成", 7),
new VideoOrder("20193232424", "Idea全套教程", 21));
//交集
List<VideoOrder> intersectionList = videoOrders1.stream().filter(videoOrders2::contains).collect(Collectors.toList());
System.out.println("交集=:"+intersectionList);
//差集1
List<VideoOrder> diffList1 = videoOrders1.stream().filter(obj -> !videoOrders2.contains(obj)).collect(Collectors.toList());
System.out.println("差集1="+diffList1);
//差集2
List<VideoOrder> diffList2 = videoOrders2.stream().filter(obj -> !videoOrders1.contains(obj)).collect(Collectors.toList());
System.out.println("差集2="+diffList2);
//并集
List<VideoOrder> allVideoOrder = videoOrders1.parallelStream().collect(Collectors.toList());
allVideoOrder.addAll(videoOrders2);
System.out.println("并集="+allVideoOrder);
//去重并集
List<VideoOrder> allVideoOrderDistinct = allVideoOrder.stream().distinct().collect(Collectors.toList());
System.out.println("去重并集="+allVideoOrderDistinct);
//两个订单平均价格
double videoOrderAvg1 = videoOrders1.stream().collect(Collectors.averagingInt(VideoOrder::getMoney));
System.out.println("订单1平均价格="+videoOrderAvg1);
double videoOrderAvg2 = videoOrders2.stream().collect(Collectors.averagingInt(VideoOrder::getMoney));
System.out.println("订单2平均价格="+videoOrderAvg2);
//两个订单总价格
long sum1 = videoOrders1.stream().collect(Collectors.summarizingInt(VideoOrder::getMoney)).getSum();
System.out.println("订单1总价格="+sum1);
long sum2 = videoOrders2.stream().collect(Collectors.summarizingInt(VideoOrder::getMoney)).getSum();
System.out.println("订单2总价格="+sum2);
}
Stream API的引入极大地简化了Java中对集合数据的操作,通过一系列链式调用的方法,可以非常方便地对数据进行过滤、映射、聚合等多种操作。无论是简单的数据处理任务还是复杂的业务逻辑,Stream API都能提供简洁而强大的解决方案。希望本文的示例能够帮助您更好地理解和应用这一强大的特性。
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- igbc.cn 版权所有 湘ICP备2023023988号-5
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务