慎用Java Collection的contains函数
背景 最近碰到一个坑,看代码:
@Test
public void should_can_get_true_when_given_matched_type() {
List numberList = Lists.newArrayList(1, 2, 34, 4);
Boolean contain = numberList.contains(2);
assertThat(contain).isTrue();
}@Test
public void should_can_get_false_when_given_not_matched_type() {
List numberList = Lists.newArrayList(1, 2, 34, 4);
Boolean contain = numberList.contains(2L);
// List 去判断 Long 类型元素assertThat(contain).isFalse();
}
这里更改了待判断参数类型,并不报错,只是返回 false。
原因 以ArrayList 为例,发现源码如下:
public int indexOf(Object o) {
if (o == null) {
for (int i = 0;
i < size;
i++)
if (elementData[i]==null)
return i;
} else {
for (int i = 0;
i < size;
i++)
if (o.equals(elementData[i]))
return i;
}
return -1;
}
而对于包装类型,复写了equals方法
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value =https://www.it610.com/article/= ((Integer)obj).intValue();
}
return false;
}
也就是说,对于同类型的对象,才去比较值来判断是否“相等”。
改进
有些集合的原生函数不建议使用,比如Collections.contains/remove/Object.equals等。
改进一
@Component
public class MyCollectionUtils {
public Boolean contained(Collection collection, T element) {
return collection.contains(element);
}
}
使用时,明确指定要检测的元素类型。
@Autowired
private MyCollectionUtils myCollectionUtilsInteger;
// 对集合和待检查元素都校验类型@Autowired
private MyCollectionUtils myCollectionUtilsString;
@Test
public void should_can_get() {
Boolean result = myCollectionUtilsInteger.contained(Lists.newArrayList(1, 2, 34, 4), 2);
assertThat(result).isTrue();
}@Test
public void should_can_get2() {
Boolean result = myCollectionUtilsString.contained(Lists.newArrayList("2", "s", "s", "333"), "2");
assertThat(result).isTrue();
}
每次根据需要注入不同类型的校验工具对象,检查性很强,不过这样做也有缺点,就是不同类型时,产生多个对象。
改进二
代码差不多,只不过只作为一个静态函数而已。
public class MyCollectionUtils {
public static Boolean contains(Collection collection, T element) {
return collection.contains(element);
}
}
使用时,如果类型不一致,编译报错。
@Test
public void should_compile_error_when_given_un_matched_type() {
List numberList = Lists.newArrayList(1, 2, 34, 4);
// MyCollectionUtils.contains(numberList, 2L);
// 类型不一致,直接编译错误
}
【慎用Java Collection的contains函数】
推荐阅读
- JAVA(抽象类与接口的区别&重载与重写&内存泄漏)
- 事件代理
- Java|Java OpenCV图像处理之SIFT角点检测详解
- java中如何实现重建二叉树
- 数组常用方法一
- 【Hadoop踩雷】Mac下安装Hadoop3以及Java版本问题
- Java|Java基础——数组
- RxJava|RxJava 在Android项目中的使用(一)
- java之static、static|java之static、static final、final的区别与应用
- Java基础-高级特性-枚举实现状态机