Day17 -集合-set实现类 2015/04/27 1、Set 一个不包含重复元素无序的集合。 遍历Set的方法:迭代器和增强for 。 注意:(1)不能用普通for,因为set元素是无序的没有角标,无法遍历。 (2)在用迭代器的时候要注意并发修改异常问题。 实现类:hashset treeset 2、HashSet hashset底层数据结构是哈希表。 创建集合对象: Collection<E> c = new HashSet<E>();//多态 Set<E> set = new HashSet<E>();//多态 HashSet<E> hs = new HashSet<E>(); HashSet在遍历自定义对象时的一些问题: (1)HashSet是保证元素的唯一性的原理? HashSet的底层数据结构是哈希表,它依赖hashCode()和equals()两个方法判断对象唯一。首先判断对象的hashCode()值是否相同。如果不同就直接添加到集合;如果相同,继续走equals(),看返回值是true还是false,若是true说明有元素重复则该元素不添加到集合中,若是false说明元素不重复则该元素添加到集合中。 (2)如何解决HashSet在存数元素时去除重复元素? HashSet底层数据结构是哈希表,而哈希表是根据哈希算法存储对象的哈希值,然而不同对象的哈希值是不一样的。因此,首先要重写hashCode()方法,返回值变为0.然后重写equals()方法,比较对象的成员变量。重写完毕之后对象的哈希值都是0,这时候存储时哈希表结构会提供哈希桶结构用于处理哈希值相同的情况。这时对象都会存储到哈希桶结构中,但是它们还是会继续执行equals()方法,因此直接比较成员变量是否相同即可。 (3)去除重复元素问题解决了,但是效率又出问题了,怎样解决? 在重写两个方法时发现equals()方法比较的是成员变量,没办法改进,因此只能在hashCode()方法上改进。一般来说,在hashCode()方法上不会直接返回一个固定的值,这个值应该是变化的,又因为这个方法本质的跟对象的成员变量相关,因此只需要把对象的成员变量值相加即可。如果是引用(对象)类型的变量用哈希值,如果是基本类型直接用值。 示例(以学生类):Return this.name.hashCode()+this.age+this.sex+this.score; (4)开发中如何重写hashCode()方法和equals()方法呢? hashCode():public int hashCode(){ Return this.name.hashCode()+this.age; } Equals(): if(this == obj) Return true; If(!(obj instanceOf Student)) Return false; If(this.name.equals(s.name) && this.age == s.age) Return false; 3、TreeSet 底层数据结构是二叉树结构。 存储自定义对象时: 保证元素排序有两种方式: (1)自然顺序,让对象所属的类去实现Comparable接口。无参构造。 (2)比较器接口Comparator。带参构造。 在自然顺序中,是如何保证排序的? 根据返回值: 正数 说明元素比以前的元素大,向后放; 负数 说明元素比以前的元素小,向前放; 0 说明元素是相同的就不添加,保证元素的唯一性。 很多时候,别人给我们的需求其实只是一个主要的需求,还有很多次要的需求是需要我们自己进行分析的! 在比较器中,是如何保证排序的? 新建一个类(MyComparator),用来实现比较器接口,重写比较器里的方法。如果实现类只需要使用一次的话就使用匿名内部类来实现。 匿名内部类(回顾) Treeset是如何存储数据的呢? 规则: (1)第一个添加的数据作为根节点; (2)从第二个开始,每一个数据从根节点开始比较: 如果大了,向右放; 如果小了,向左放; 如果相同,替换。 TreeSet是如何获取数据的呢? 从根节点开始,获取数据的规则是按照每个数据的左、中、右原则。最后是按照从小到大的顺序获取数据。 开发原则:对修改关闭,对扩展开放。 4、Collection集合的工具类—Collections Collection 和collection 的区别? Collection:是collection集合的顶层接口,定义了collection集合的共性方法。 Collections:是一个类,定义了针对Collection集合操作的功能。有排序、查找、反转等。 Collection的功能: 排序: 二分查找: 反转: 最大值: 随机置换:
|