List的removeAll()方法与equals()方法之坑
来源:互联网 发布:剑网三不合法的脸数据 编辑:程序博客网 时间:2024/06/05 10:43
最新在项目中遇到一个坑,大概如下:
public class MainTest { public static void main(String[] args) { //创建一个List1对象,添加四个元素 List<Operator> list1 = new ArrayList<>(); Operator op1 = new Operator(0, "first operator", "1"); Operator op2 = new Operator(0, "second operator", "2"); Operator op3 = new Operator(0, "second operator", "2"); Operator op4 = new Operator(0, "second operator", "3"); list1.add(op1); list1.add(op2); list1.add(op3); list1.add(op4); //再创建另一个list2对象,添加一个与之前list1添加过的元素属性相同的元素, Operator op = new Operator(0, "second operator", "2"); List<Operator> list2 = new ArrayList<>(); list2.add(op); //从list1中删掉list2 list1.removeAll(list2); }}
其中Operator是我自定义的类。我的本意是,从从list1中删掉list2后,list1中应该只剩下两个元素:op1和op4了吧,可是结果却不是这样,而是只剩下op1了。
这是怎么回事呢?查找半天才发现,原因出在Operator类的实现上:
class Operator{ int id; String msg; String extra; public Operator(int id, String msg, String extra) { super(); this.id = id; this.msg = msg; this.extra = extra; } @Override public String toString() { return "Operator [id=" + id + ", msg=" + msg + ", extra=" + extra + "]"; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Operator other = (Operator) obj; if (id != other.id) return false; if (msg == null) { if (other.msg != null) return false; } else if (!msg.equals(other.msg)) return false; return true; }}
具体原因就是我重写了Operator类的equals()方法,而在此方法中,我只比较了Operator对象的id和msg属性,而并未比较extra属性。
而重写equals()方法和removeAll()有什么关系呢?看源码:
removeAll()的方法实现在java.util.AbstractCollection类中:
public boolean removeAll(Collection<?> c) { Objects.requireNonNull(c); boolean modified = false; Iterator<?> it = iterator(); while (it.hasNext()) { if (c.contains(it.next())) { it.remove(); modified = true; } } return modified; }
其中调用了contains()方法,一块贴上源码:
public boolean contains(Object o) { Iterator<E> it = iterator(); if (o==null) { while (it.hasNext()) if (it.next()==null) return true; } else { while (it.hasNext()) if (o.equals(it.next()))//这里调用了equals()方法 return true; } return false; }
List的removeAll()方法会最终会调用equals()方法判断需要删除哪些元素!
在此例中,removeAll()传入的参数list2含有元素op,op会和list1中的元素逐个用equals()进行比较,结果,因为equals()方法不比较extra属性,因此op 和 op2, op3, op4的比较结果都是相同的,结果list1就删的只剩下了op1了。
如果把Operator类中重写的equals()方法去掉,再运行,会是什么结果呢?
去掉的话,Operator类就是Object类默认的equals()方法,会用”==”进行对象的比较,也就是比较地址。因此op和list1中的任意一个元素比较都是不相等的。结果就是,list1中不会删除任何元素。
阅读全文
1 0
- List的removeAll()方法与equals()方法之坑
- List的removeAll方法异常?
- List的Clear方法与RemoveAll方法用法小结
- List 的 removeAll 方法的效率
- List的clear()方法和removeAll()方法 的区别
- Java 集合之List 集合的删除方法顺序分析以及remove和removeAll区别
- 如何使用Java List等集合类的removeAll方法
- 如何使用Java List等集合类的removeAll方法
- 如何使用Java List等集合类的removeAll方法
- Java List等集合类的removeAll方法
- 如何使用Java List等集合类的removeAll方法
- 如何使用Java List等集合类的removeAll方法
- 如何使用Java List等集合类的removeAll方法
- 如何使用Java List等集合类的removeAll方法
- 如何使用Java List等集合类的removeAll方法
- 关于list中的removeAll方法使用说明
- Session方法Clear、RemoveAll、Abandon的联系与区别之我见
- List 的removeall需要重写equals才有效
- Android CheckBox setButtonDrawable(null) 在 4.x 版本中无效
- CentOS操作系统下安装Java Web应用攻略(上)
- Mybatis和Spring整合
- Vue之路之--vue的初体验
- 数据库设计的三大范式
- List的removeAll()方法与equals()方法之坑
- hdu1754
- Emacs(二)——移动光标
- HashMap与HashTable的区别
- 树莓派之简介及参数
- 查找——斐波那契查找法
- Android ContentResolver 获取手机联系人
- Leetcode 57. Insert Interval
- python金融数据分析1:tushare使用