Springboot内置的工具类之CollectionUtils

news2024/11/25 0:38:00

前言

        实际业务开发中,集合的判断和操作也是经常用到的,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中失败了");
}

T lastElement(List list)

返回 List 中最后一个元素。

@Test
public void test8(){
    Employee lisi = new Employee("lisi");
    Employee zhangsan    = new Employee("zhangsan");
    List<Employee > list=new ArrayList<>();
    list.add(zhangsan);
    list.add(lisi);
    Employee employee = CollectionUtils.lastElement(list);
    Assert.isTrue(employee.equals(lisi), "获取集合最后一个元素失败了");
}

T firstElement(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), "获取集合第一个元素失败了");

}

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, "把数据转换成集合失败了");
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/89419.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

交换机(Exchange)

目录一、Exchange(交换机)的作用二、Exchange(交换机)的类型1.直连交换机&#xff1a;Direct Exchange2.主题交换机&#xff1a;Topic Exchange3.扇形交换机&#xff1a;Fanout Exchange4.首部交换机&#xff1a;Headers exchange5.默认交换机6.Dead Letter Exchange&#xff0…

一文入坑【Canvas】多图与案例详解

游戏玩法 游戏主要考验玩家的空间感和记忆能力&#xff0c;玩家需要通过开局的3秒内尽可能多的记忆两个空间内相同元素的位置&#xff0c;3秒后将会翻牌把图案盖住&#xff0c;玩家需要点击卡牌来翻转牌面&#xff0c;两张相同图案的卡牌即可保留&#xff0c;游戏计时将在卡牌…

小型水库雨水情测报及大坝安全监测建设介绍

一、背景介绍 二、站点布设 布局示意图&#xff1a; 红色&#xff1a;坝轴线 兰色&#xff1a;监测横断面&#xff0c;一般不少于3个&#xff0c;300m内间距2050m&#xff0c;300m外间距5010m。黄色:监测纵断面&#xff0c;一般不少于4个。上游坝坡正常蓄水位以上应布设1个。…

ssm+Vue计算机毕业设计校园闲置物品管理系统的实现(程序+LW文档)

ssmVue计算机毕业设计校园闲置物品管理系统的实现&#xff08;程序LW文档&#xff09; 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff0…

WPF TreeView拖动排序拖拽排列

底部附有Demo示例。需要的朋友可以去下载参考 一、图示 先上图&#xff0c;不知为啥&#xff0c;GIF总看起来特别卡&#xff0c;实际却很流畅。 由于录制问题&#xff0c;GIF动画只会播放一次&#xff0c;需要重复观看的&#xff0c;请将网页关闭后重新打开再观看 WPF的资料…

自动化运维与普通运维有什么区别?

本文首发于知乎&#xff0c;由嘉为蓝鲸原创。 商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处。 01. 何为自动化运维&普通运维&#xff1f; 在了解两者的区别前&#xff0c;我们得先明确对二者的定义&#xff0c;总的来说运维工作的目的都是为了保障企业业…

Gateway简介

文档&#xff1a;Spring Cloud Gateway 小结&#xff1a; nacos &#xff1a;注册中心&#xff0c;解决服务的注册与发现 nacos &#xff1a;配置中心&#xff0c;配置文件中心化管理 Ribbon&#xff1a;客户端负载均衡器&#xff0c;解决微服务集群负载均衡的问题 Openfeign…

网络工程毕业设计 SSM游戏攻略资讯补丁售卖系统(源码+论文)

文章目录1 项目简介2 实现效果2.1 界面展示3 设计方案3.1 概述3.2 系统流程3.3 系统结构设计4 项目获取1 项目简介 Hi&#xff0c;各位同学好呀&#xff0c;这里是M学姐&#xff01; 今天向大家分享一个今年(2022)最新完成的毕业设计项目作品&#xff0c;【基于SSM的游戏攻略…

容器安全——云原生中镜像容器全生命周期防护思路

文章目录容器简介容器镜像传统安全面对容器安全的表现无法匹配动态IP无法侦测到容器内的各种行为无法扫描各种分层存储的镜像文件无法适应新的容器引擎和框架镜像容器全生命周期的安全防护Build防护Ship防护Run防护容器简介 我们都知道&#xff0c;VM是通过Hypervisor虚拟化技…

没有备份电脑照片怎么恢复?分享3种找回照片方法

随着科学技术的不断发展&#xff0c;越来越多的人喜欢使用手机或相机进行拍摄&#xff0c;但是这些设备存储照片量多后&#xff0c;容易导致卡顿甚至无法拍摄的情况发生&#xff0c;对此&#xff0c;婚纱/新闻/美食/广告摄影等职业人员&#xff0c;会习惯性将这些设备上的照片导…

VR如何改变办公场所,听一听Meta的预测

近期&#xff0c;为了更好的了解人们对于元宇宙、VR的看法&#xff0c;以及这对办公场景带来的影响&#xff0c;Meta对全球2000多名企业员工和400名企业领导进行调研。调查结果显示&#xff0c;66%的受调查者认为VR有助于还原线下办公的团结感&#xff08;togetherness&#xf…

Linux系统Initramfs机制

概述 现代Linux系统都使用到了一种功能比较特殊的微型系统&#xff0c;作为Linux内核初始化完成但未进入最终系统时的过渡系统&#xff0c;主要的目的是为了将最终系统载入到根文件系统上&#xff0c;辅助内核启动最终系统&#xff0c;可以称之为“辅助系统”。 辅助系统的作…

【C语言数据结构(基础篇)】第三站:链表(一)

目录 一、动态顺序表的缺陷以及链表的引入 1.动态顺序表的缺陷&#xff0c;以及链表的引入 2. 链表的概念 3.链表的声明 4.链表的逻辑结构与物理结构 二、单链表的实现 1.单链表的创建 2.单链表的打印 3.单链表的尾插 4.单链表的头插 5.单链表的头删、尾删 6.查找链表…

WPF入门第四篇 WPF模板

WPF模板 1、ControlTemplate 上一篇已经试用过控件模板&#xff0c;我们知道WPF的控件都是继承自Control&#xff0c;在Control类中有一个Template属性&#xff0c;类型就是ControlTemplate。那么利用这个ControlTemplate就可以彻底的颠覆控件的默认外观。 <Window x:Cla…

如何使用Unity ARFoundation和XR Interaction Toolkit对Prefab进行选择、缩放、移动、和旋转操作?

本文分享一种很常见的AR体验的实现。这种AR体验即&#xff0c;手机相机检测到指定图片/平面/实物之后&#xff0c;虚拟模型随之出现&#xff0c;并允许用户在屏幕上使用手势&#xff08;例如双指捏合&#xff09;对该虚拟模型进行选择、缩放、移动、和旋转操作。 这种体验有很…

【Spring】——14、如何使用@Value注解为bean的属性赋值呢?

&#x1f4eb;作者简介&#xff1a;zhz小白 公众号&#xff1a;小白的Java进阶之路 专业技能&#xff1a; 1、Java基础&#xff0c;并精通多线程的开发&#xff0c;熟悉JVM原理 2、熟悉Java基础&#xff0c;并精通多线程的开发&#xff0c;熟悉JVM原理&#xff0c;具备⼀定的线…

flask之g对象、flask-session使用、数据库连接池、信号

目录 g对象 flask-session的使用 数据库连接池 flask中集成mysql wtfroms使用(了解) 信号 g对象 全称global&#xff0c;是一个全局对象在此次请求过程中一直有效&#xff0c;其实就是请求的上下文从请求进来就一直存在直到请求结束&#xff0c;所以在当次请求过程中&…

华为云WeLink云空间,企业的多啦A梦「百宝袋」办公助手

我们知道&#xff0c;源自华为19万员工的数字化办公实践的华为云WeLink&#xff0c;作为新一代智能工作平台、远程办公平台、移动办公平台、协同办公软件&#xff0c;已经给成为企业数字化转型的连接器。今天&#xff0c;我们来聊一聊WeLink提供的一项优质服务——云空间。 We…

论文复现-2代码研读:Black-Box Tuning for Language-Model-as-a-Service

第一步&#xff1a;将作者所给代码跑通。 下载代码&#xff0c;放置在本地文件夹。 报错问题一&#xff1a; 使用hugging face 中loaddataset函数报错。显示connect error。 修改如下&#xff1a;将数据集下载文件.py文件在本地&#xff0c;然后从.py文件中加载数据集。 解决…

【深度学习】PyTorch深度学习实践 - Lecture_13_RNN_Classifier

文章目录一、问题描述二、OurModel三、准备数据3.1 Data Convert3.2 Padding Data3.3 Label Convert四、双向RNN五、PyTorch代码实现5.1 引入相关库5.2 创建Tensors函数5.3 将名字转化为字符列表函数5.4 国家名字数据集对象5.5 RNN&#xff08;GRU&#xff09;分类器对象5.6 训…