Java--Stream的两个小用法(去重+map排序)

本文介绍 JDK 1.8 中 Stream API 的两个实用技巧:一是如何实现列表元素去重,包括基本类型包装类和自定义对象;二是如何根据 Map 的 key 对 List 进行排序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

分享两个jdk1.8中stream的小技巧

一.stream去重:

1.List元素是基本类型的包装类

List<String> list= Arrays.asList("Xiaoming","Xiaohong","Xiaogang","Xiaoming");
		list.stream().distinct().forEach(e-> System.out.println(e));
List<Integer> list2= Arrays.asList(1,2,3,1);
		list2.stream().distinct().forEach(e-> System.out.println(e));

stream默认去重效果如下:
在这里插入图片描述

2.List元素自定义对象

有如下对象
在这里插入图片描述
准备List:

/**
* 19-7-16、7-15、7-14、7-16
 */
List<Student> list= Arrays.asList(
	new Student("小明","男",new Date(1563206400000L))
	,new Student("小刚","男",new Date(1563120000000L))
	,new Student("小红","女",new Date(1563033600000L))
	,new Student("小明","男",new Date(1563206400000L)));
list.stream().distinct().forEach(e-> System.out.println(e));

stream默认去重效果:
在这里插入图片描述
并没有去重,因为第一个小明和第四个小明是不同的对象引用。将第一个小明和第四个换成同一个引用:

Student one=new Student("小明","男",new Date(1563206400000L));
List<Student> list= Arrays.asList(one
								 ,new Student("小刚","男",new Date(1563120000000L))
							 	 ,new Student("小红","女",new Date(1563033600000L))
								 ,one);
list.stream().distinct().forEach(e-> System.out.println(e));

去重效果:
在这里插入图片描述)
证明默认是判断对象引用是否相同。那如何根据对象的某个属性去重呢?
有如下自定义函数:

/**
* stream去重自定义函数
* @param keyExtractor
* @param <T>
* @return
*/
public static <T> Predicate<T> distinctByField(Function<? super T, Object> keyExtractor) {
	Map<Object, Boolean> seen = new ConcurrentHashMap<>(16);
	return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
}

根据学生名字去重代码:

/**
* 19-7-16、7-15、7-14、7-16
*/
List<Student> list= Arrays.asList(
			new Student("小明","男",new Date(1563206400000L))
		    ,new Student("小刚","男",new Date(1563120000000L))
			,new Student("小红","女",new Date(1563033600000L))
			,new Student("小明","男",new Date(1563206400000L)));
list.stream().filter(distinctByField(e->e.getName())).forEach(e-> System.out.println(e));

自定义去重效果:
在这里插入图片描述

二.List根据map的key排序map

有如下自定义根据map属性排序list函数:

/**
 * 自定义Map属性排序List方法
 * @param map
*/
private static String comparingByBirth(Map<String, Object> map){
		return map.get("birth").toString();
}

准备数据:

/**
 * 19-7-15、7-14、7-16
 */
List<Map<String,Object>> list=new ArrayList<>();
Map<String,Object> map=new LinkedHashMap<>();
map.put("name","小明");
map.put("sex","男");
map.put("birth","2019-07-15");
list.add(map);
Map<String,Object> map2=new LinkedHashMap<>();
map2.put("name","小红");
map2.put("sex","女");
map2.put("birth","2019-07-14");
list.add(map2);
Map<String,Object> map3=new LinkedHashMap<>();
map3.put("name","小刚");
map3.put("sex","男");
map3.put("birth","2019-07-16");
list.add(map3);
list.stream().sorted(Comparator.comparing(Test::comparingByBirth))
				.forEach(e-> System.out.println(e));

排序(默认升序)后效果:
在这里插入图片描述

三.总结

①排序可使用日期的字符串形式(- or /),也可以使用Date类型,但注意自定义函数返回值类型也要修改为Date
②想要排序结果为降序(在sorted中调用reversed即可):

list.stream().sorted(Comparator.comparing(Test::comparingByBirth).reversed())
				.forEach(e-> System.out.println(e));

③注意去重和排序的调用方式不同
④以上两个自定义函数是网上找的,底层如何执行并不了解,有兴趣的可以自己搜一下

萌新发言,不喜勿喷,欢迎指出不当之处。

根据提供的引用内容,使用streammap的方法如下所示: 首先,创建一个List来存储Map对象: ``` List<Map<String, String>> list = new ArrayList<>(); Map<String, String> map = new HashMap<>(); map.put("id", "id1"); map.put("name", "name1"); map.put("age", "22"); list.add(new HashMap<>(map)); map.put("id", "id1"); map.put("name", "name1"); map.put("age", "22"); list.add(new HashMap<>(map)); map.put("id", "id1"); map.put("name", "name2"); map.put("age", "22"); list.add(new HashMap<>(map)); map.put("id", "id2"); map.put("name", "name2"); map.put("age", "32"); list.add(new HashMap<>(map)); ``` 然后,使用stream和collect方法结合起来,使用Collectors.collectingAndThen方法和TreeSet来复的map对象,通过对比id和name字段来判断两个map是否相等: ``` list = list.stream() .collect(Collectors.collectingAndThen( Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing((o) -> o.get("id") + ";" + o.get("name")))), ArrayList::new)); ``` 这样,list中的map对象就会被,只保留一个拥有相同id和name字段的map对象。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Java--Stream两个用法+map排序)](https://blog.youkuaiyun.com/GuessBUG/article/details/96109069)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [使用Stream流对List中的Map进行多条件](https://blog.youkuaiyun.com/wounler/article/details/121522761)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值