packagecom.alpha.demo;importjava.util.HashSet;importjava.util.Set;classBook {privateString title;privatedouble price;publicBook(String title,double price) {this.title= title;this.price= price; } @OverridepublicinthashCode() {finalint prime =31;int result =1;long temp; temp =Double.doubleToLongBits(price); result = prime * result + (int) (temp ^ (temp >>>32)); result = prime * result + ((title ==null) ?0:title.hashCode());return result; } @Overridepublicbooleanequals(Object obj) {if (this== obj)returntrue;if (obj ==null)returnfalse;if (getClass()!=obj.getClass())returnfalse;Book other = (Book) obj;if (Double.doubleToLongBits(price) !=Double.doubleToLongBits(other.price))returnfalse;if (title ==null) {if (other.title!=null)returnfalse; } elseif (!title.equals(other.title))returnfalse;returntrue; } @OverridepublicStringtoString() {return"Book [title="+ title +", price="+ price +"]\n"; }}publicclassTestDemo { publicstaticvoidmain(String[] args) throwsException {Set<Book> all =newHashSet<Book>();all.add(newBook("Java",69.8));all.add(newBook("Java",69.8)); // 全部属性相同all.add(newBook("JSP",69.8)); // 部分属性相同all.add(newBook("Oracle",79.8)); // 全都不同System.out.println(all); }}
以后在非排序的情况下,只要是判断重复元素依靠的永远都是hashCode()与equals()。
一些简单的源码解析
HashSet是不允许存在重复元素的,分析其源码,来观察其底层的实现原理:
publicclassHashSet<E>extendsAbstractSet<E>implementsSet<E>,Cloneable, java.io.Serializable{ /** * 内部维护着一个HashMap */privatetransientHashMap<E,Object> map;// map中key的默认值privatestaticfinalObject PRESENT =newObject(); /** * HashSet的默认构造函数为内部维护的HashMap实例化 */publicHashSet() { map =newHashMap<>(); } /** * 添加时将PRESENT与要添加的元素作为map的key与value添加至维护的map中 * * @param e element to be added to this set * @return {@code true} if this set did not already contain the specified * element */publicbooleanadd(E e) {returnmap.put(e, PRESENT)==null; }}