Java 集合 HashSet以及LinkedHashSet 详细图解!!

HashSet

HashSet底层存储数据使用数组+链表的方式进行存储

HashSet添加数据的过程

存储数据时,计算HashCode,计算出来的HashCode再通过散列函数计算出其在数组中的索引位置,HashCode类似于地址,两个不相同的元素值计算出来的Hash值一般不同,但是通过散列函数计算之后,不同HashCode可能映射为同一个数组的索引位置,这就需要再通过equals方法来比较两者是否真的相同了,如果不相同,那么以链表的方式也连接到该索引值下,如果相同那么不进行重复存储

如图

请添加图片描述

在JDK7中相同,链表插入方式为新的在数组中,旧的元素以链表方式链在外面

JDK8及以上版本,旧的元素在数组里面,新的元素以链表方式链在外面 ------七上八下

test

public class SetTest {
    public static void main(String[] args) {
        Set set = new HashSet();

        Employee e1 = new Employee("Tom",18,new MyDate(2002,3,5));
        Employee e2 = new Employee("Jerry",19,new MyDate(2001,6,5));

        set.add(e1);
        set.add(e2);
        System.out.println(set);

        System.out.println("************test1*************");
        e1.setName("Mary");
        System.out.println(set);

        System.out.println("************test2*************");
        set.remove(e1);
        System.out.println(set);

        System.out.println("************test3*************");
        set.add(new Employee("Mary",18,new MyDate(2002,3,5)));
        System.out.println(set);

        System.out.println("************test4*************");
        set.add(new Employee("Tom",18,new MyDate(2002,3,5)));
        System.out.println(set);

    }

}

结果

请添加图片描述

结果分析

对于test1,没问题,改变了Set中元素的值,打印Set中的内容也是改变之后的值

对于test2,移除e1,结果看到没有移除掉,这是因为在Set中插入元素时,该元素在数组中存储的位置是通过之前的名为Tom的e1计算的,修改e1的值之后位置并未改变,还是名为Tom的e1位置;remove()方法需要先找到e1,但是通过修改后的e1(名字改为Mary)的hashCode()以及equals()计算之后与之前名为Tom的不一样,所以没找到,所以移除不掉

对于test3,因为Mary占的是Tom的位置,所以再插入一个一样的Mary之后并不会形成hashCode()的冲突,所以插入成功

对于test4,虽然Mary占了Tom的位置,但是不是Tom,所以新插入的Tom经过hashCode()计算之后虽然和Mary相同,但是其equals()与Mary不同,所以以链表的方式放在Mary旁边,插入也成功了


LinkedHashSet

LinkedHashSet是HashSet的子类,它可以按照插入顺序,对Set进行遍历

因为其在向Set内部存储时还加入了两对引用(双向链表)

如下图

请添加图片描述

因为有这样的结构所以可以进行按照插入顺序的遍历

LinkedHashSet也多使用于需要频繁通过插入顺序遍历的情况

Java集合体系主要分为两大接口,分别是Collection和Map。其中,Collection接口下主要有List、Set和Queue三大子接口,而Map是一个独立的接口。 1. List:有序的集合,可以包含重复的元素。主要的实现类有ArrayList、LinkedList和Vector。其中,ArrayList是基于动态数组的实现,适合随机访问;LinkedList是基于链表的实现,适合插入和删除操作。Vector是线程安全的ArrayList。 2. Set:不允许包含重复元素的集合。主要的实现类有HashSetLinkedHashSet和TreeSet。HashSet基于HashMap实现,LinkedHashSet基于LinkedHashMap实现,TreeSet基于TreeMap实现,它们分别以HashMap、LinkedHashMap和TreeMap为基础提供元素的添加、删除和查找操作。 3. Queue:一种特殊的List,主要用于元素的排队等候处理。主要的实现类有PriorityQueue、LinkedList和ArrayDeque。PriorityQueue是基于优先队列的实现,而LinkedList可以作为队列使用,ArrayDeque则是一个基于数组的双端队列。 4. Map:一种键值对集合,一个Map中包含key-value对,其中key不能重复。主要的实现类有HashMap、LinkedHashMap、TreeMap、Hashtable和Properties。HashMap是基于散列实现的,适用于插入、删除、查找;LinkedHashMap是有序的,按照插入的顺序或者访问顺序记录键值对;TreeMap是基于红黑树实现,适用于排序的场景;Hashtable是线程安全的HashMap;Properties是Hashtable的子类,用于处理属性文件。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值