前言
实际业务开发中,集合的判断和操作也是经常用到的,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,
"把数据转换成集合失败了");
-
}
伙计,看完赶紧收藏+关注,省得用的时候找不着!
转载:https://blog.csdn.net/fox9916/article/details/128321098