collection的remove方法对HashSet ArrayList的不同

来源:互联网 发布:深入理解java 虚拟机 编辑:程序博客网 时间:2024/05/24 04:36

ArrayList底层是一个数组,每次加入就是依次向后加入,当删除的时候,比较的是传入的参数是否equals保存在ArrayList中的某个元素,与Hashcode无关,所以一个类如果仅仅重写了equals方法而没有重写hashcode方法,这要两个对象equals返回true,那么就可以成功删除。

HashSet底层是HashMap,根据前面的介绍必须使用hashcodeequals来查找到待删除的元素,所以仅仅重写equals而没有重写hashcode是删除不了的。

 

Address类首先仅仅重写了equals方法,而没有重写hashcode方法

public class Address{private String detail;public Address(String detail){this.detail = detail;}public String getDetail(){return detail;}public void setDetail(String detail){this.detail = detail;}//@Override//public int hashCode()//{//final int prime = 31;//int result = 1;//result = prime * result + ((detail == null) ? 0 : detail.hashCode());//return result;//}@Overridepublic boolean equals(Object obj){if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;Address other = (Address) obj;if (detail == null){if (other.detail != null)return false;}else if (!detail.equals(other.detail))return false;return true;}}

 

下面在ArrayList 和HashSet中测试以两个equals的对象,一个加入,然后使用另外一个删除

public static void main(String[] args) throws Throwable{Address a1 = new Address("shanghai");Address a2 = new Address("shanghai");ArrayList<Address> list = new ArrayList<Address>();list.add(a1);list.remove(a2);//加入a1,然后根据a2删除,能成功删除, list为空System.out.println(list.isEmpty());HashSet<Address> set = new HashSet<Address>();set.add(a1);set.remove(a2);//同样的操作在HashSet中就不管用,删除不了,set不为空System.out.println(set.isEmpty());}

 

下面把上面Address类中的重写hashcode方法的注释取消掉,结果是无论ArrayList还是HashCode都能成功删除

 

在没有重写hashcode的情况下,如果向set中加入两个equals的对象是可以的,例如:

HashSet<Address> set = new HashSet<Address>();set.add(a1);set.add(a2);Object[] as = set.toArray();//set中的两个对象是相等的,这样就出现了代码不健壮的情况System.out.println(as[0].equals(as[1]));


 

总结:

ArrayList底层是数组,可以加入重复的,使用remove删除时判断的标准是equals方法。

HashSet底层是一个HashMap,不能加入重复的,重复的标准是先比较hashcode,然后比较equals,使用remove删除时同样是这样的比较原则

 

1 0
原创粉丝点击