Springboot内置的工具类之CollectionUtils示例讲解
作者:凡夫贩夫 发布时间:2023-08-23 20:47:13
前言
实际业务开发中,集合的判断和操作也是经常用到的,Spring也针对集合的判断和操作封装了一些方法,但是最令我惊讶的是,我在梳理这些内容的过程中发现了一些有趣的现象,我的第一反应是不敢相信,再想一想,没错,我是对的。所以强烈建议大家可以认真看完这篇文章,这一篇绝对有价值,因为有趣的是我我竟然发现了Spring的两个bug。
org.springframework.util.CollectionUtils
集合的判断
boolean hasUniqueObject(Collection collection)
从源码注释上看,是用于判断 List/Set 中的每个元素是否唯一,即 List/Set 中不存在重复元素。但这里要告诉大家千万不要用这个方法,因为这个方法有bug,为什么呢?下面是Spring-core-5.2.13.RELEASE.jar中的源码,且看12行,细心的人会发现两个对象之间比较是否相等用的是!=。还记得“==”和“equals”的区别吗?“==”操作符专门用来比较两个变量的值是否相等,equals()方法是用于比较两个独立对象的内容是否相同。所以这里如果集合中的元素是数值,可以用“==”比较,如果是普通的引用对象,就得不到正确的结果了。
public static boolean hasUniqueObject(Collection<?> collection) {
if (isEmpty(collection)) {
return false;
}
boolean hasCandidate = false;
Object candidate = null;
for (Object elem : collection) {
if (!hasCandidate) {
hasCandidate = true;
candidate = elem;
}
else if (candidate != elem) {
return false;
}
}
return true;
}
boolean containsInstance(Collection collection, Object element)
从源码的注释上看,是用于判断集合中是否包含某个对象。这个方法也不建议使用,因为与上一个方法存在相同的问题,且看源码的第4行,依然用的是“==”。
public static boolean containsInstance(@Nullable Collection<?> collection, Object element) {
if (collection != null) {
for (Object candidate : collection) {
if (candidate == element) {
return true;
}
}
}
return false;
}
boolean isEmpty(Collection collection)
这个方法已验证过可以放心用,用于判断 List/Set 是否为空;
@Test
public void test1(){
Collection<String> list=new ArrayList<>();
boolean empty = CollectionUtils.isEmpty(list);
Assert.isTrue(empty, "集合list不为空");
System.out.println("集合list增加一元素");
list.add("happy");
boolean empty2 = CollectionUtils.isEmpty(list);
Assert.isTrue(empty2, "集合list不为空");
}
boolean isEmpty(Map map)
用于判断 Map 是否为空。
@Test
public void test2(){
Map<String,String> map = new HashMap<>();
boolean empty = CollectionUtils.isEmpty(map);
Assert.isTrue(empty, "map不为空");
System.out.println("map中增加元素");
map.put("name", "jack");
boolean empty2 = CollectionUtils.isEmpty(map);
Assert.isTrue(empty2, "map不为空");
}
boolean containsAny(Collection source, Collection candidates)
从源码上的注释看,是用于判断集合source中是否包含另一个集合candidates的任意一个元素,即集合candidates中的元素是否完全包含于集合soruce。
从源码这个方法中的元素之间的比较用到了“equals”方法,且调用的是集合内对象的equals方法,因此使用这个方法想要得到正确的结果的前提是,比较的对象要重写hashCode()和eauals()方法。
@Test
public void test4(){
Employee lisi = new Employee("lisi");
Employee zhangsan = new Employee("zhangsan");
Employee wangwu = new Employee("wangwu");
List<Employee > list=new ArrayList<>();
list.add(zhangsan);
list.add(lisi);
List<Employee> list2=new ArrayList<>();
list2.add(wangwu);
//这里可以用是因为比较的时候调用的是equals方法
boolean b = CollectionUtils.containsAny(list, list2);
Assert.isTrue(b, "list1没有包含有list2中任意一个元素");
}
集合的操作
void mergeArrayIntoCollection(Object array, Collection collection)
将数组array中的元素都添加到 List/Set 中。
@Test
public void test6(){
List<Employee > list=new ArrayList<>();
Employee lisi = new Employee("lisi");
list.add(lisi);
Employee zhangsan = new Employee("zhangsan");
Employee[] employees={zhangsan};
CollectionUtils.mergeArrayIntoCollection(employees, list);
Assert.isTrue(list.size()==2, "把数据中的元素合并到list失败了");
}
void mergePropertiesIntoMap(Properties props, Map map)
将 Properties 中的键值对都添加到 Map 中。
@Test
public void test7(){
Properties properties = new Properties();
properties.setProperty("name", "zhangsan");
Map<String,String > map = new HashMap<>();
CollectionUtils.mergePropertiesIntoMap(properties, map);
Assert.isTrue(map.get("name").equals("zhangsan"), "把properties中的元素合并到map中失败了");
}
@Test
public void test7(){
Properties properties = new Properties();
properties.setProperty("name", "zhangsan");
Map<String,String > map = new HashMap<>();
CollectionUtils.mergePropertiesIntoMap(properties, map);
Assert.isTrue(map.get("name").equals("zhangsan"), "把properties中的元素合并到map中失败了");
}
T lastElement(List list)
返回 List 中最后一个元素。
@Test
public void test9(){
Employee lisi = new Employee("lisi");
Employee zhangsan = new Employee("zhangsan");
List<Employee > list=new ArrayList<>();
list.add(zhangsan);
list.add(lisi);
Employee employee = CollectionUtils.firstElement(list);
Assert.isTrue(employee.equals(zhangsan), "获取集合第一个元素失败了");
}
T firstElement(List list)
返回集合中第一个元素。
@Test
public void test10(){
Employee zhangsan = new Employee("zhangsan");
Employee[] employees={zhangsan};
List list = CollectionUtils.arrayToList(employees);
Assert.isTrue(list.size()==1, "把数据转换成集合失败了");
}
List arrayToList(Object source)
把一个数组转换成一个集合。
@Test
public void test10(){
Employee zhangsan = new Employee("zhangsan");
Employee[] employees={zhangsan};
List list = CollectionUtils.arrayToList(employees);
Assert.isTrue(list.size()==1, "把数据转换成集合失败了");
}
来源:https://blog.csdn.net/fox9916/article/details/128321098


猜你喜欢
- Android之禁止ViewPager滑动实现实例当我们想在同一个Activity或者Fragment中展示多个页面时往往会用到ViewPa
- 一、概述从3.1版本起,Spring框架就已经支持将缓存添加到现有的Spring应用中,和事务支持一样,缓存抽象允许在对代码影响最小的情况下
- 本文实例讲述了java使用dom4j生成与解析xml文档的方法。分享给大家供大家参考,具体如下:xml是一种新的数据格式,主要用于数据交换。
- 本文基于GP58系列,它可以兼容ESC/POS指令集,对EPSON的打印机通用.Android下的设备调试,如果设备提供了驱动,按照厂家的驱
- 本文实例为大家分享了OpenGL绘制Bezier曲线的具体代码,供大家参考,具体内容如下最近在看Francis S Hill ,Jr 和 S
- 后台生成验证码工具方法 /* * 设置图片的背景色 */ public static v
- 接触Spring快半年了,前段时间刚用Spring4+S2H4做完了自己的毕设,但是很明显感觉对Spring尤其是IOC容器的实现原理理解的
- 1、前言在日常的Spring Boot项目开发中,我们都会建立几个固有的包,分别是Controller、entity(pojo)、dao、s
- 本文主要介绍了25行Java代码将普通图片转换为字符画图片和文本的实现,分享给大家,具体如下:原图生成字符画文本(像素转换字符显示后,打开字
- 本文实例为大家分享了Mybatis分页插件使用的具体代码,供大家参考,具体内容如下1.分页插件简介pagehelper源码都说这是史上最好用
- 本节,我们从Rxjava使用代码入手,去结合自己已有的知识体系,加查阅部分源码验证的方式,来一起探索一下Rxjava实现的基本原理。为了本文
- 本文运用图片给大家介绍了C#如何检查foreach判读其是否为null,我们下面话不多说,直接来看内容吧。1、foreach遍历列表或数组时
- 目录生成器设计类图: 实现代码:优点:用途与缺点:责任链设计类图:实现代码:优点:用途和缺点:总结生成器生成器模式:封装一个产品的
- 前言内存治理一直是每个开发者最关心的问题,我们在日常开发中会遇到各种各样的内存问题,比如OOM,内存泄露,内存抖动等等,这些问题都有以下共性
- 前言前面文章我们介绍了Broker是如何将消息全量存储到CommitLog文件中,并异步生成dispatchRequest任务更新Consu
- 首先,需要一个电话号码,目前很多账户都是将账户名设置成手机号,然后点击按钮获取手机验证码。 其次,你需要后台给你手机短信的验证接口,各个公司
- 本文实例展示了C#自定义函数NetxtString实现生成随机字符串的方法,在进行C#项目开发中非常实用!分享给大家供大家参考。一、生成随机
- 工厂模式工厂模式顾名思义就是生产实例的工厂,使用工厂模式不会在程序中使用new关键字创建实例。而是将创建对象的细节隐藏,对外提供统一的方法,
- 本文实例讲述了C#获取指定PDF文件页数的方法。分享给大家供大家参考。具体如下:using System;using System.IO;u
- springboot返回文件流@GetMapping(value = "/file/{fileName}")public