刨析源码,深层讲解 Java-集合框架( 五 )


2.1 如果hash值不相同,则元素a添加成功 。—>情况2
2.2 如果hash值相同,进而需要调用元素a所在类的()方法:
()返回true,元素a添加失败
()返回false,则元素a添加成功 。—>情况3
对于添加成功的情况2和情况3而言:元素a与已经存在指定索引位置上数据以链表的方式存储 。
jdk 7 :元素a放到数组中,指向原来的元素 。
jdk 8 :原来的元素在数组中,指向元素a
口诀:七上八下
4.2.3 代码演示
@Testpublic void test(){Set set = new HashSet();set.add(456);set.add(123);set.add(123);set.add("AA");set.add("CC");set.add(new User("Tom",12));set.add(new User("Tom",12));set.add(129);Iterator iterator = set.iterator();while(iterator.hasNext()){System.out.println(iterator.next());}//AA//CC//129//456//User@621be5d1//User@573fd745//123}
4.3 Set实现类之二: 4.3.1 概述
?是的子类 。
?根据元素的值来决定元素的存储位置,但它同时使用双向链表维护元素的次序,这使得元素看起来是以插入顺序保存的 。在添加数据的同时,每个数据还维护了两个引用,记录此数据前一个数据和后一个数据 。
? 插入性能略低于,但在迭代访问Set里的全部元素时有很好的性能 。对于频繁的遍历操作,效率高于 。
?不允许集合元素重复 。
4.3.2 代码演示
@Testpublic void test(){Set set = new LinkedHashSet();set.add(456);set.add(123);set.add(123);set.add("AA");set.add("CC");set.add(new User("Tom",12));set.add(new User("Tom",12));set.add(129);Iterator iterator = set.iterator();while(iterator.hasNext()){System.out.println(iterator.next());}//456//123//AA//CC//User@621be5d1//User@573fd745//129////Process finished with exit code 0}
4.4 Set实现类之三: 4.4.1 概述
? 是接口的实现类,可以确保集合元素处于排序状态 。
? 底层使用红黑树结构存储数据 。
? 向中添加的数据,要求是相同类的对象 。
?两种排序方法:自然排序和定制排序 。默认情况下,采用自然排序 。
特点:有序,查询速度比List快
4.4.2 排序—自然排序
? 如果试图把一个对象添加到时,则该对象的类必须实现接口,实现的接口的类必须实现( obj) 方法,两个对象即通过( obj) 方法的返回值来比较大小 。
? 向中添加元素时,只有第一个元素无须比较()方法,后面添加的所有元素都会调用()方法进行比较 。
? 因为只有相同类的两个实例才会比较大小,所以向中添加的应该是同 一个类的对象 。
? 对于集合而言,它判断两个对象是否相等的唯一标准是:两个对象通过 ( obj)方法比较返回值 。
? 当需要把一个对象放入中,重写该对象对应的 () 方法时,应保证该方法与 ( obj) 方法有一致的结果:如果两个对象通过 () 方法比较返回 true,则通过 ( obj)方法比较应返回 0 。否则,让人难以理解 。
4.4.3 排序—定制排序
? 的自然排序要求元素所属的类实现接口,如果元素所属的类没有实现接口,或不希望按照升序(默认情况)的方式排列元素或希望按照 其它属性大小进行排序,则考虑使用定制排序 。
? 定制排序,通过接口来实现 。需要重写(T o1,T o2)方法 。
? 利用int (T o1,T o2)方法,比较o1和o2的大小:如果方法返回正整数,则表示o1大于o2;如果返回0,表示相等;返回负整数,表示o1小于o2 。
? 要实现定制排序,需要将实现接口的实例作为形参传递给的构 造器 。此时,仍然只能向中添加类型相同的对象 。否则发生异常 。
? 使用定制排序判断两个元素相等的标准是:通过比较两个元素返回了0 。