项目代码中遇到了一个问题,用到List的contains,方法如下:
List<Integer> newIds = Lists.newArrayList(1,2,3,4,5);
List<Integer> ids = DemoService.getServerIds(gid); // 调用mybatis返回,数据库存的是:4,5
newIds.forEach(item ->{
if(ids.contains(item)){
System.out.println(true);
}else {
System.out.println(false);
}
});
正常情况下,应该会输出两个true 才对的,因为数据库返回的是4,5。但是,执行完之后,只会输出false,这就奇怪了,难道是contains方法不是这么用的?不可能啊,看了下源码:
public boolean contains(Object o) {
return indexOf(o) >= 0;
}
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;
}
最终调用的是对象的equal方法,我这里List<Integer>里存的是Integer的对象,照理说,他们值相等的话,equal方法应该返回true才对啊,为什么只返回了false,百思不得其解,然后自己新建了两个List<Integer>,不走Mybatis,结果发现,这回的输出就是正确的了。挖槽,这就耐人寻味了,都是List<Integer>,怎么就不一样了,不过可以定位的是和Mybatis有关,然后去看看sql那里有问题,额,发现了罪魁祸首:
<select id="getServerIds" resultType="String">
……
</select>
resultType=String,原来,返回回去的是个List<String>,这样和Integer去匹配当然不行了。额,你可能会问不对啊,上面这句代码List<Integer> ids = DemoService.getServerIds(gid); // 调用mybatis返回,数据库存的是:4,5 返回的是List<Integer>啊,怎么会成了List<String>,这一点就要去熟悉的了解下java的泛型了,具体这里就不多解释了,总之改成resultType=Integer后问题解决,在这里记录下。