Stream Api实用操作
AI-摘要
WenXi GPT
AI初始化中...
介绍自己
生成本文简介
推荐相关文章
前往主页
前往tianli博客
List转Map
1、利用Collectors.toMap方法进行转换
public Map<Long, String> getIdNameMap(List<Account> accounts) {
return accounts.stream().collect(Collectors.toMap(Account::getId, Account::getUsername));
}
2、收集对象实体本身
在开发过程中我们也需要有时候对自己的list中的实体按照其中的一个字段进行分组(比如 id ->List),这时候要设置map的value值是实体本身。
public Map<Long, Account> getIdAccountMap(List<Account> accounts) {
return accounts.stream().collect(Collectors.toMap(Account::getId, account -> account));
}
public Map<Long, Account> getIdAccountMap(List<Account> accounts) {
return accounts.stream().collect(Collectors.toMap(Account::getId, Function.identity()));
}
3、重复key的情况
在list转为map时,作为key的值有可能重复,这时候流的处理会抛出个异常:Java.lang.IllegalStateException:Duplicate key。这时候就要在toMap方法中指定当key冲突时key的选择。(这里是选择第二个key覆盖第一个key)
public Map<String, Account> getNameAccountMap(List<Account> accounts) {
return accounts.stream().collect(Collectors.toMap(Account::getUsername, Function.identity(), (key1, key2) -> key2));
}
4、用groupingBy进行分组
根据一个字段或者属性分组也可以直接用groupingBy方法,很方便。
//分组
Map<Integer, List<User>> personGroups =
userList.stream().collect(Collectors.groupingBy(User::getAge));
//分组,某字段之和
Map<Integer, List<User>> personGroups =
userLIst.stream().mapToInt(User::getAge).sum();
5、用partitioningBy进行分块
分块根据判断条件,分为判断结果为true和判断条件为false的两块集合
Map<Boolean, List<User>> children =
userList.stream().collect(Collectors.partitioningBy(p -> p.getAge() < 18));
//"年龄小于18:" + children.get(Boolean.TRUE);
//"年龄大于18:" + children.get(Boolean.FALSE);
List检查是否存在元素,anyMatch()、allMatch()、noneMatch()
List<Integer> list = Arrays.asList(1, 2, 3);
// anyMatch,判断条件里,任意一个元素满足,返回true
boolean flag = List.stream().anyMatch(i -> i > 1); // true
// allMatch,判断条件里,所有元素都满足,才返回true
boolean flag = list.stream().allMatch(i -> i > 1); //false
// noneMatch,判断条件里,所有元素都不满足,才返回true
boolean flag = list.stream().noneMatch(i -> i > 1); //false
List去重
//list去重
List<Integer> list = Arrays.asList(1, 1, 2, 3, 3);
List<Integer> distinctList = list.stream().distinct().collect(Collectors.toList());
//list对象,单字段去重
List<User> userList =
userList.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(User :: getUserid))), ArrayList::new));
//list对象,多字段组合去重
List<User> userList =
userList.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(o -> {
return o.getUserId()+","+o.getAge();
}))),ArrayList::new));
//filter去重
List<Student> studentList = studentList.stream().filter(distinctByKey(Student::getName)).collect(Collectors.toList());
private static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
Set<Object> seen = ConcurrentHashMap.newKeySet();
return t -> seen.add(keyExtractor.apply(t));
}
提取List集合的一列
List<String> userNameList =
userList.stream().map(User::getUserName).collect(Collectors.toList());
List<String> userNameList = userList.stream().map(user->{
return user.getRealName()
};
过滤出List中符合条件的元素
List<User> userList = userList.steam().filter(user -> a.getAge > 18 ).collect(Collectors.toList());
求List中某个元素之和
BigDecimal totalAge =
userList.stream().map(User::getAge).reduce(BigDecimal.ZERO, BigDecimal::add);
Integer int = userList.stream().collect(Collectors.summingInt(User::getAge));
Integer int = userLIst.stream().mapToInt(User::getAge).sum();
#备注:集合中累加得字段不允许为NULL
List对象过滤掉符合List属性元素
List<Integer> list = Arrays.asList(18,19,20);
List<User> filterList = userList.stream().filter(i ->!list.contains(i.getAge())).collect(Collectors.toList());
map() 转换
List<Integer> list = Arrays.asList(1, 2, 3);
List<String> newList = list.stream().map(i -> i * i).map(String::valueOf).collect(Collectors.toList());
// ["1", "4", "9"]
List排序
List<类> list; 代表某集合
//返回 对象集合以类属性一升序排序
list.stream().sorted(Comparator.comparing(类::属性一));
//返回 对象集合以类属性一降序排序 注意两种写法
list.stream().sorted(Comparator.comparing(类::属性一).reversed());//先以属性一升序,结果进行属性一降序
list.stream().sorted(Comparator.comparing(类::属性一,Comparator.reverseOrder()));//以属性一降序
//返回 对象集合以类属性一升序 属性二升序
list.stream().sorted(Comparator.comparing(类::属性一).thenComparing(类::属性二));
//返回 对象集合以类属性一降序 属性二升序 注意两种写法
list.stream().sorted(Comparator.comparing(类::属性一).reversed().thenComparing(类::属性二));//先以属性一升序,升序结果进行属性一降序,再进行属性二升序
list.stream().sorted(Comparator.comparing(类::属性一,Comparator.reverseOrder()).thenComparing(类::属性二));//先以属性一降序,再进行属性二升序
//返回 对象集合以类属性一降序 属性二降序 注意两种写法
list.stream().sorted(Comparator.comparing(类::属性一).reversed().thenComparing(类::属性二,Comparator.reverseOrder()));//先以属性一升序,升序结果进行属性一降序,再进行属性二降序
list.stream().sorted(Comparator.comparing(类::属性一,Comparator.reverseOrder()).thenComparing(类::属性二,Comparator.reverseOrder()));//先以属性一降序,再进行属性二降序
//返回 对象集合以类属性一升序 属性二降序 注意两种写法
list.stream().sorted(Comparator.comparing(类::属性一).reversed().thenComparing(类::属性二).reversed());//先以属性一升序,升序结果进行属性一降序,再进行属性二升序,结果进行属性一降序属性二降序
list.stream().sorted(Comparator.comparing(类::属性一).thenComparing(类::属性二,Comparator.reverseOrder()));//先以属性一升序,再进行属性二降序
//空/Null数据排序
list.stream().sorted(Comparator.comparing(类::属性一).thenComparing(item -> item.属性二, Comparator.nullsLast(Date::compareTo))).collect(Collectors.toList());
//空/Null数据分组
Map<String, List<类>> map = list.stream().collect(Collectors.groupingBy(item -> {
if (item.属性一 == null || item.属性一.equals("")) {
return "";
}
return DateFormat.getDateInstance().format(item.属性一);
}))
flatMap() 展开子集合
// 假设现在有一组用户列表,每个用户有多个爱好
User user1 = new User().setId(1).setName("张三").setHobbies(Arrays.asList("看书", "听音乐"));
User user2 = new User().setId(2).setName("李四").setHobbies(Arrays.asList("看电影", "乒乓球"));
User user3 = new User().setId(3).setName("王五").setHobbies(Arrays.asList("爬山", "履行"));
List<User> users = Arrays.asList(user1, user2, user3);
// 要获取所有用户的所有的爱好,只需要这样
List<String> hobbies = users.stream().flatMap(user -> user.getHobbies().stream()).collect(Collectors.toList());
// [看书, 听音乐, 看电影, 乒乓球, 爬山, 履行]
count()计数
List<Integer> list = Arrays.asList(1, 2, 3);
long count = list.stream().filter(i -> i > 2).count();
skip()、limit() 分页
Stream.iterate(1, prev -> prev + 1) //1开始,自增1的无限序列
.skip(6) // 跳过前6个
.limit(3) // 取3个元素
.forEach(System.out::print);
reduce() 聚合
List<Integer> list = Arrays.asList(1, 2, 3, 4);
// 初始值为0,累加所有元素
Integer sum1 = list.stream().reduce(0, (x, y) -> x + y);
// 无初始值,计算结果为Optional,需要处理为空的情况后才能使用,因为结果stream中可能没有元素
Integer sum2 = list.stream().reduce(Integer::sum).orElse(0);
// 聚合时目标类型和Stream中元素类型不同时,使用此重载方法
BigDecimal sum3 = list.stream()
.reduce(
BigDecimal.ZERO, //初始值
(prev, i) -> prev.add(BigDecimal.valueOf(i)), // 转换成目标类型后累加
BigDecimal::add // 多线程的parallelStream中,对每个线程的累加结果进行汇总的方法
);
peek() 预览
String result = Stream.of(1, 2, 3, 4)
.map(i -> i * i)
// 在流处理过程中提前窥视一下当前数据的样子
// 这里会分别打印出 1, 4, 9, 16
.peek(System.out::println)
.map(i -> i * 2)
.map(String::valueOf)
.collect(Collectors.joining(","));
Stream的收集器
// 收集到ArrayList中
List<Integer> list = Stream.of(1, 2, 3).collect(Collectors.toList());
// 收集到HashSet中
Set<Integer> set = Stream.of(1, 2, 3).collect(Collectors.toSet());
// 收集到HashMap中
Map<Integer, User> map = Stream.of(
new User().setId(1).setName("Tom"),
new User().setId(2).setName("Jeff"),
new User().setId(3).setName("Jack")
).collect(Collectors.toMap(
User::getId, // 获取key的Function
Function.identity()// 获取value的Function
)
);
// 自定义收集器
// 第一种方式,用于Collection接口的子类,可以定义具体的实现类
LinkedList<Integer> linkedList = Stream.of(1, 2, 3)
.collect(Collectors.toCollection(LinkedList::new));
// 第二种方式,用于任何集合,是最灵活的方式
HashSet<Integer> set = Stream.of(1, 2, 3)
.collect(
HashSet::new, // 定义一个用来收集结果的容器
HashSet::add, // 定义每个元素通过什么方法收集到容器中
HashSet::addAll // 定义并发情况下如何合并多个容器的结果
);
聚合收集器
jdk内置了很多聚合收集器,其中reducing最为灵活,可以实现其他聚合收集器的功能。 包括:
Collectors.summingInt() 求和
Collectors.averagingInt() 求平均值
Collectors.maxBy() 求最大值
Collectors.minBy() 求最小值
Collectors.counting() 计数
Collectors.joining() 字符串连接
Collectors.reducing() 自定义聚合
// summing 求和
Integer sumResult = Stream.of(1, 2, 3, 4).collect(Collectors.summingInt(Integer::valueOf));
// averaging 求平均值
Double avgResult = Stream.of(1, 2, 3, 4).collect(Collectors.averagingInt(Integer::valueOf);
// maxBy,minBy 求最大最小值
Optional<Integer> maxResult = Stream.of(1, 2, 3, 4).collect(Collectors.maxBy(Comparator.comparingInt(Integer::valueOf)));
// counting 计数
Long countResult = Stream.of(4, 3, 2, 1).collect(Collectors.counting());
// joining 字符串连接
String joinResult = Stream.of("a", "b", "c", "d").collect(Collectors.joining("|"));
// reduce 自定义方式求和
Integer reduceResult = Stream.of(1, 2, 3, 4)
// 两个参数分别为初始结果值和累加函数
// 初始结果0, 每次遍历时当前元素和结果如何进行性累加
.collect(Collectors.reducing(0, Integer::sum));
//求最大最小某字段,返回实体
User maxAgeUser = users.stream().max(Comparator.comparing(User::getAge)).get();
//求最大/最小值
int maxAge01 = users.stream().max(Comparator.comparing(User::getAge)).get().getAge();
double maxAge02 = users.stream().mapToDouble(User::getAge).max().getAsDouble();
//平均值
double avgAge01 = users.stream().mapToInt(User -> User.getAge()).average().getAsDouble();
- 感谢你赐予我前进的力量
赞赏者名单
因为你们的支持让我意识到写文章的价值🙏
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 平凡先生/文奚
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果