Springboot内置的工具类之CollectionUtils

前言

实际业务开发中,集合的判断和操作也是经常用到的,Spring也针对集合的判断和操作封装了一些方法,但是最令我惊讶的是,我在梳理这些内容的过程中发现了一些有趣的现象,我的第一反应是不敢相信,再想一想,没错,我是对的。所以强烈建议大家可以认真看完这篇文章,这一篇绝对有价值,因为有趣的是我我竟然发现了Spring的两个bug。

Springboot内置的工具类之CollectionUtils

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, "&#x96C6;&#x5408;list&#x4E0D;&#x4E3A;&#x7A7A;");
    System.out.println("&#x96C6;&#x5408;list&#x589E;&#x52A0;&#x4E00;&#x5143;&#x7D20;");
    list.add("happy");
    boolean empty2 = CollectionUtils.isEmpty(list);
    Assert.isTrue(empty2, "&#x96C6;&#x5408;list&#x4E0D;&#x4E3A;&#x7A7A;");
}</string>

boolean isEmpty(Map map)

用于判断 Map 是否为空。

@Test
public void test2(){
    Map<string,string> map = new HashMap<>();
    boolean empty = CollectionUtils.isEmpty(map);
    Assert.isTrue(empty, "map&#x4E0D;&#x4E3A;&#x7A7A;");
    System.out.println("map&#x4E2D;&#x589E;&#x52A0;&#x5143;&#x7D20;");
    map.put("name", "jack");
    boolean empty2 = CollectionUtils.isEmpty(map);
    Assert.isTrue(empty2, "map&#x4E0D;&#x4E3A;&#x7A7A;");
}</string,string>

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);
    //&#x8FD9;&#x91CC;&#x53EF;&#x4EE5;&#x7528;&#x662F;&#x56E0;&#x4E3A;&#x6BD4;&#x8F83;&#x7684;&#x65F6;&#x5019;&#x8C03;&#x7528;&#x7684;&#x662F;equals&#x65B9;&#x6CD5;
    boolean b = CollectionUtils.containsAny(list, list2);
    Assert.isTrue(b, "list1&#x6CA1;&#x6709;&#x5305;&#x542B;&#x6709;list2&#x4E2D;&#x4EFB;&#x610F;&#x4E00;&#x4E2A;&#x5143;&#x7D20;");
}</employee></employee>

集合的操作

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, "&#x628A;&#x6570;&#x636E;&#x4E2D;&#x7684;&#x5143;&#x7D20;&#x5408;&#x5E76;&#x5230;list&#x5931;&#x8D25;&#x4E86;");
}</employee>

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"), "&#x628A;properties&#x4E2D;&#x7684;&#x5143;&#x7D20;&#x5408;&#x5E76;&#x5230;map&#x4E2D;&#x5931;&#x8D25;&#x4E86;");
}</string,string>

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), "&#x83B7;&#x53D6;&#x96C6;&#x5408;&#x6700;&#x540E;&#x4E00;&#x4E2A;&#x5143;&#x7D20;&#x5931;&#x8D25;&#x4E86;");
}</employee>

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), "&#x83B7;&#x53D6;&#x96C6;&#x5408;&#x7B2C;&#x4E00;&#x4E2A;&#x5143;&#x7D20;&#x5931;&#x8D25;&#x4E86;");

}</employee>

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, "&#x628A;&#x6570;&#x636E;&#x8F6C;&#x6362;&#x6210;&#x96C6;&#x5408;&#x5931;&#x8D25;&#x4E86;");
}

伙计,看完赶紧收藏+关注,省得用的时候找不着!
Springboot扩展点系列实现方式、工作原理集合:
Springboot扩展点之ApplicationContextInitializer
Springboot扩展点之BeanDefinitionRegistryPostProcessor
Springboot扩展点之BeanFactoryPostProcessor
Springboot扩展点之BeanPostProcessor
Springboot扩展点之InstantiationAwareBeanPostProcessor
Springboot扩展点之SmartInstantiationAwareBeanPostProcessor
Springboot扩展点之ApplicationContextAwareProcessor
Springboot扩展点之@PostConstruct
Springboot扩展点之InitializingBean
Springboot扩展点之DisposableBean
Springboot扩展点之SmartInitializingSingleton
Springboot核心功能工作原理:
Springboot实现调度任务的工作原理
Springboot事件监听机制的工作原理

Original: https://blog.csdn.net/fox9916/article/details/128321098
Author: 凡夫贩夫
Title: Springboot内置的工具类之CollectionUtils

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/756957/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • torch.Tensor详解

    Data typedtypeCPU tensorGPU tensor32-bit floating point or 64-bit floating point or 16-bit…

    Python 2023年8月23日
    034
  • 集成学习之Stacking(堆栈)方法

    文章目录 集成学习(Ensemble learning) Stacking(堆栈)方法定义 Stacking中的交叉验证 Stacking中的过拟合问题 其他 集成学习(Ensem…

    Python 2023年9月16日
    049
  • Python3 零基础自学笔记_pytest框架

    pytest命名规则 测试文件以test_开头(以_test结尾也可以) 测试类以Test开头(驼峰命名法),并且不能带有 init 方法 测试函数以test_开头 断言使用ass…

    Python 2023年9月13日
    051
  • CE Loss与BCE Loss的区别

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

    Python 2023年10月10日
    028
  • pytorch:常见的pytorch参数初始化方法总结

    pytorch参数初始化 * – 1. 关于常见的初始化方法 – + 1) 均匀分布初始化torch.nn.init.uniform_() + 2) 正态分…

    Python 2023年9月27日
    066
  • flask篇B2,重定向,url_for,模板语法

    重定向与url_for 在app1.py文件中 from flask import Flask, request, redirect,url_for from flask impo…

    Python 2023年8月12日
    055
  • 二本学历5年经验的程序员,出去面试被碾压~

    目录 1、从一个求职案例引入 2 、学历差距:面试官的第一印象 3、公司背景差距:你的人生名片 4、技术差距:硬核能力的欠缺 5、架构能力的差距 6、面试结果的分析 这篇文章,聊一…

    Python 2023年11月9日
    032
  • python 调整子图布局_matplotlib中精确调整子图形大小

    我在A4纸上绘制一些索引数据,用3×2行列的6幅图像绘制。我已经得到了基本的代码工作,它将这个数据帧数据绘制成以下6个图。在def plot_idx(df,image,k…

    Python 2023年9月4日
    025
  • numpy学习笔记

    Numpy 一、ndarray 二、基本操作 三、生成数组 * 1、生成0和1的数组 2、从现有数组生成 3、生成固定范围的数组 4、生成随机数组 5、 数组的索引、切片、形状修改…

    Python 2023年8月27日
    063
  • Python语言Numpy包之Meshgrid 函数

    在 Numpy 的官方文章里, meshgrid 函数的英文描述也显得文绉绉的,理解起来有些难度。可以这么理解, meshgrid 函数用两个坐标轴上的点在平面上画网格。 用法: …

    Python 2023年8月24日
    067
  • numpy 排序,搜索和计数

    排序numpy.sort() numpy.sort(a[, axis=-1, kind=’quicksort’, order=None]) Return a sorted copy…

    Python 2023年8月24日
    042
  • Pandas进阶柒 缺失数据

    Pandas进阶柒 缺失数据 pandas进阶系列根据datawhale远昊大佬的joyful pandas教程写一些自己的心得和补充,本文部分引用了原教程,并参考了《利用Pyth…

    Python 2023年8月22日
    047
  • Libgdx游戏开发(2)——接水滴游戏实现

    原文:Libgdx游戏开发(2)——接水滴游戏实现 – Stars-One的杂货小窝 本文使用Kotlin语言开发 通过本文的学习可以初步了解以下基础知识的使用: Ba…

    Python 2023年10月20日
    035
  • 2022年最新优化算法—蛛母狼马蜂算法(论文创新点)

    前言 凡是机械、电子、计算机这一块,搞科研的小伙伴应该都知道,一个好的算法往往是科研论文的主要创新点。每年都会有许多层出不穷的算法,算法的相互融合和吸收各自的优点已不再是新鲜事!那…

    Python 2023年9月30日
    048
  • Python番外篇:selenium+matplotlib 爬取天气预报 制作温度折线图

    hello,大家好,我是wangzirui32,今天我们来学习如何使用selenium+matplotlib来爬取天气预报,并制作未来气温折线图。先来看看成品:好了,看到了我们的成…

    Python 2023年9月6日
    051
  • Pytest_allure 数据驱动框架分享

    啊哦~你想找的内容离你而去了哦 内容不存在,可能为如下原因导致: ① 内容还在审核中 ② 内容以前存在,但是由于不符合新 的规定而被删除 ③ 内容地址错误 ④ 作者删除了内容。 可…

    Python 2023年9月13日
    053
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球