Springboot內(nèi)置的工具類(lèi)之CollectionUtils示例講解
前言
實(shí)際業(yè)務(wù)開(kāi)發(fā)中,集合的判斷和操作也是經(jīng)常用到的,Spring也針對(duì)集合的判斷和操作封裝了一些方法,但是最令我驚訝的是,我在梳理這些內(nèi)容的過(guò)程中發(fā)現(xiàn)了一些有趣的現(xiàn)象,我的第一反應(yīng)是不敢相信,再想一想,沒(méi)錯(cuò),我是對(duì)的。所以強(qiáng)烈建議大家可以認(rèn)真看完這篇文章,這一篇絕對(duì)有價(jià)值,因?yàn)橛腥さ氖俏椅揖谷话l(fā)現(xiàn)了Spring的兩個(gè)bug。

org.springframework.util.CollectionUtils
集合的判斷
boolean hasUniqueObject(Collection collection)
從源碼注釋上看,是用于判斷 List/Set 中的每個(gè)元素是否唯一,即 List/Set 中不存在重復(fù)元素。但這里要告訴大家千萬(wàn)不要用這個(gè)方法,因?yàn)檫@個(gè)方法有bug,為什么呢?下面是Spring-core-5.2.13.RELEASE.jar中的源碼,且看12行,細(xì)心的人會(huì)發(fā)現(xiàn)兩個(gè)對(duì)象之間比較是否相等用的是!=。還記得“==”和“equals”的區(qū)別嗎?“==”操作符專(zhuān)門(mén)用來(lái)比較兩個(gè)變量的值是否相等,equals()方法是用于比較兩個(gè)獨(dú)立對(duì)象的內(nèi)容是否相同。所以這里如果集合中的元素是數(shù)值,可以用“==”比較,如果是普通的引用對(duì)象,就得不到正確的結(jié)果了。
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)
從源碼的注釋上看,是用于判斷集合中是否包含某個(gè)對(duì)象。這個(gè)方法也不建議使用,因?yàn)榕c上一個(gè)方法存在相同的問(wèn)題,且看源碼的第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)
這個(gè)方法已驗(yàn)證過(guò)可以放心用,用于判斷 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中是否包含另一個(gè)集合candidates的任意一個(gè)元素,即集合candidates中的元素是否完全包含于集合soruce。
從源碼這個(gè)方法中的元素之間的比較用到了“equals”方法,且調(diào)用的是集合內(nèi)對(duì)象的equals方法,因此使用這個(gè)方法想要得到正確的結(jié)果的前提是,比較的對(duì)象要重寫(xiě)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);
//這里可以用是因?yàn)楸容^的時(shí)候調(diào)用的是equals方法
boolean b = CollectionUtils.containsAny(list, list2);
Assert.isTrue(b, "list1沒(méi)有包含有l(wèi)ist2中任意一個(gè)元素");
}
集合的操作
void mergeArrayIntoCollection(Object array, Collection collection)
將數(shù)組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, "把數(shù)據(jù)中的元素合并到list失敗了");
}
void mergePropertiesIntoMap(Properties props, Map map)
將 Properties 中的鍵值對(duì)都添加到 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 中最后一個(gè)元素。
@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), "獲取集合第一個(gè)元素失敗了");
}
T firstElement(List list)
返回集合中第一個(gè)元素。
@Test
public void test10(){
Employee zhangsan = new Employee("zhangsan");
Employee[] employees={zhangsan};
List list = CollectionUtils.arrayToList(employees);
Assert.isTrue(list.size()==1, "把數(shù)據(jù)轉(zhuǎn)換成集合失敗了");
}
List arrayToList(Object source)
把一個(gè)數(shù)組轉(zhuǎn)換成一個(gè)集合。
@Test
public void test10(){
Employee zhangsan = new Employee("zhangsan");
Employee[] employees={zhangsan};
List list = CollectionUtils.arrayToList(employees);
Assert.isTrue(list.size()==1, "把數(shù)據(jù)轉(zhuǎn)換成集合失敗了");
}
到此這篇關(guān)于Springboot內(nèi)置的工具類(lèi)之CollectionUtils的文章就介紹到這了,更多相關(guān)Springboot內(nèi)置的工具類(lèi)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Mybatis中流式查詢(xún)的實(shí)現(xiàn)示例
MyBatis的ResultHandler是用于處理數(shù)據(jù)庫(kù)查詢(xún)結(jié)果集的工具,可以通過(guò)回調(diào)函數(shù)對(duì)數(shù)據(jù)進(jìn)行流式處理,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2024-09-09
Java連接Linux服務(wù)器過(guò)程分析(附代碼)
這篇文章主要介紹了Java連接Linux服務(wù)器過(guò)程分析(附代碼),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-12-12
RocketMQ?broker?消息投遞流程處理PULL_MESSAGE請(qǐng)求解析
這篇文章主要為大家介紹了RocketMQ?broker?消息投遞流程處理PULL_MESSAGE請(qǐng)求源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04
IntelliJ IDEA2019實(shí)現(xiàn)Web項(xiàng)目創(chuàng)建示例
這篇文章主要介紹了IntelliJ IDEA2019實(shí)現(xiàn)Web項(xiàng)目創(chuàng)建示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04

