12、集合--HashSet的使用
HashSet是Set接口的典型实现
大多数时候使用Set集合时就是使用这个实现类
按Hash算法来存储其中的元素,因此具有很好的存取和查询性能
特点:
1、不能保证元素的排序、顺序有可能发生变化(无序)
2、HashSet不是同步的,如果多个线程同时访问一个HashSet,如果有2条或者两条以上的线程
同时修改了HashSet集合时,必须通过代码来保证其同部
3、结合元素可以时null
当向HashSet集合中中存入一个元素时
首先会调用hashCode()方法来得到该对象的hashCode值
然后根据hashCode值来决定该对象在HashSet中的存储位置
equals方法返回true时,hashcode值应该相等
如果两个元素通过equals()方法来比较返回true时但他们的hashCode()方法返回值不相等
HasnSet将会把他们存储在不同的位置
public boolean equals(Object o) { if (o == this) return true; if (!(o instanceof Set)) return false; Collection<?> c = (Collection<?>) o; if (c.size() != size()) return false; try { return containsAll(c); } catch (ClassCastException unused) { return false; } catch (NullPointerException unused) { return false; } }
public int hashCode() { int h = 0; Iterator<E> i = iterator(); while (i.hasNext()) { E obj = i.next(); if (obj != null) h += obj.hashCode(); } return h; }
HashSet的代码测试
public static void main(String[] args) { HashSet set = new HashSet(); Person person = new Person("AA",2); Person person1 = new Person("AA",2); Person person2 = new Person("BB",1); Person person3 = new Person("DD",4); Person person4 = new Person("CC",3); System.out.println("person调用hashCode()方法:" +person.hashCode()); System.out.println("person1调用hashCode()方法:" +person1.hashCode()); System.out.println("person3调用hashCode()方法:" + person3.hashCode()); //添加元素 set.add(person); set.add(person1); set.add(person2); set.add(person3); set.add(person4); System.out.println(set); //遍历 Iterator it = set.iterator(); while (it.hasNext()){ System.out.println("遍历:" + it.next()); } //长度 System.out.println("长度:" + set.size()); //hashCode()方法 System.out.println("set的hashCode()方法:" +set.hashCode()); //contains()是否包含某个元素 System.out.println( "测试set集合使用包含name=BB,age=1的对象:" + set.contains(new Person("BB",1))); //remove()方法移除指定元素 set.remove(new Person("BB",1)); System.out.println("移除name = BB 之后的set:" + set); HashSet set1 = new HashSet(); set1.add(person4); //retainAll()方法:删除set1中没有的元素 set.retainAll(set1); System.out.println("调用retainAll()方法 : " +set); //清空集合 set.clear(); System.out.println("清空集合之后的set:" + set); }
Person类
此时Person类重写了equals()方法和hashCode()方法
public class Person { private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; } public Person(String name, int age) { this.name = name; this.age = age; } public Person(){ } public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Person other = (Person) obj; if (age != other.age) return false; if (name == null){ if (other.name != null){ return false; } }else if (!name.equals(other.name)){ return false; } return true; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + age; result = prime * result + ((name == null) ? 0:name.hashCode()); return result; } }