Java学习笔记之集合(五):HashSet集合的实现原理

来源:互联网 发布:地图标记软件 excel 编辑:程序博客网 时间:2024/06/07 01:46
package com.collection.set;import java.util.HashSet;import java.util.Set;import org.junit.Test;/*集合的体系:----| Collection: 单例集合的根接口-------| List:实现了List接口的集合类,具备的特点:有序,可重复;----------| ArrayList:底层是维护了一个Object数组实现的;特点:查询速度快,增删慢;----------| LinkedList:底层是使用了链表数据结构实现的;特点:查询速度慢,增删快;----------| Vector(了解即可):底层也是维护了一个Object数组实现的,与ArrayList是一样的;但是Vector是线程安全的,操作效率低,所以被ArrayList取代了;ArrayList不是线程同步的,操作效率高;-------| Set:实现了Set接口的集合类,具备的特点:无序,不可重复;----------| HashSet:底层是使用了哈希表来支持的;特点:存取速度快;HashSet的实现原理:往HashSet中添加元素的时候,HashSet会先调用元素的hashCode()方法得到元素的哈希值,然后通过元素的哈希值经过移位等运算,就可以算出该元素在哈希表中的存储位置;元素的哈希值相当于元素在内存中的存储地址;算出位置之后分两种情况存储:情况一:如果算出元素存储的位置目前没有其他任何元素存在,那么该元素可以直接存储到该位置上;情况二:如果算出该元素存储的位置目前已经存在别的元素了,那么HashSet会调用元素的equels方法与该位置的元素再比较一次;如果equals返回的是true,那么该元素与这个位置上的元素就视为同一个元素,不允许添加;如果equals返回的是false,那么该元素允许添加;问题:哈希表中同一个位置可以添加多个元素吗?可以。哈希表的其中一个特点:桶式结构。也就是说哈希表中的每个位置都相当于一个桶,可以存储多个元素;----------| TreeSet:无序:指添加元素和顺序和取出元素的顺序是不一致的;*/class Person{int id;String name;public Person(int id, String name) {this.id = id;this.name = name;}@Overridepublic String toString() {return "{id=" + id + ",name=" + name + "}";}@Overridepublic int hashCode() {// 向HashSet中每添加一个元素就会调用一次元素的hashCode()方法;System.out.println("===== 调用了hashCode()方法 =====");// 重写hashCode()方法,使元素的id一样时,在哈希表中存储的是同一个位置;return this.id;}@Overridepublic boolean equals(Object obj) {// 重写equals,使id一样时,是同一个元素对象;Person p = (Person)obj;return this.id == p.id;}}public class Demo5 {@SuppressWarnings({ "rawtypes", "unchecked" })@Testpublic void test1(){Set set = new HashSet();set.add("张三");set.add("李四");set.add("王五");// 无序,不可以重复;System.out.println("添加成功了吗?" + set.add("李四")); // 元素不可重复;添加失败,返回false;System.out.println("集合中的元素:" + set); // 输出元素的顺序和添加元素的顺序是不一致的}@SuppressWarnings({ "rawtypes", "unchecked" })@Testpublic void test2(){Set set = new HashSet();set.add(new Person(1, "张三"));set.add(new Person(2, "李四"));set.add(new Person(3, "王五"));/*问题:此处元素能添加成功吗?能。因为根据上面所说的HashSet的实现原理,此处新创建的Person对象的哈希值是唯一的,所以可以添加;当重写hashCode()方法和equals()方法后,就不能添加成功了。 */System.out.println("添加成功了吗?" + set.add(new Person(2, "冯二")));System.out.println("集合中的元素:" + set);}}

原创粉丝点击