博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java Set集合详解与面试点介绍(HashSet、HashLinkedSet、TreeSet)
阅读量:2056 次
发布时间:2019-04-28

本文共 2124 字,大约阅读时间需要 7 分钟。

一、Set接口介绍

set是一个散列集合

Set特点:不包含重复元素, 如果有多个重复元素,只会显示一个。

常用子接口:<E>

常用子类:  

二、HashSet类

(1)HashSet底层数据的数据结构是HashMap,而HashMap的底层是数组+链表的结构。

特点:元素不能重复,元素的位置不是一成不变的,是无序的,线程不安全的

 

(2)HashMap底层存入数据原理:

【1】数据存入HashMap前先进行哈希算法,得到的值,在进行哈希算法(二次哈希),最后得到的结果,在0~15之间(默认的情况下)。

【2】HashMap中每一个数组的位置称之为桶(bucket),数据存入桶之前,会先和桶中的数据进行比较,如果数据相同,那么就舍弃数据,如果数据不同,那么在存入链表中。并且链表是栈结构的(先进后出)。意味着,先进来的在栈尾,后进来的在栈顶。位置改变,所以称之为无序的。

【3】HashMap每次扩容是原来容量的一倍。扩容时会重新进行二次计算,重新排列位置。这个过程称之为rehash

综上所述:元素位置改变有两点:一是链表的栈结构(先进后出),二是扩容时,进行rehash

 

(3)HashSet的初始容量为16,默认加载因子为0.75。当然也可以指定初始容量,与加载因子。

注意如下几点:

如果指定的初始容量过小,会频繁扩容,频繁的计算,效率降低。

如果指定的初始容量过大,会浪费内存。

如果加载因子过小,会频繁扩容。频繁的rehash,就会影响效率

如果加载因子过大,链表的长度会很长,查询速率就降低。

补充:

【1】HashSet指定初始容量,会自动修改为2的n次方的形式。

10 --> 16

15 -->16

7-->8

【2】在JDK1.8后,如果桶上的链表长度大于8,那么会将链表结构扭转为红黑二叉树结构。从而提升效率。

三、LinkedHashSet类

通过翻看LinkedHashSet的源码,我发现,LinkedHashSet中的构造方法,都是调用父类的,而这个父类就是HashSet。所以,它

的初始容量,加载因子扩容方式都是和HashSet一样的。唯一不同的是,它是一个双向链表,其中有一条链表,专门用来控制顺序。

(1)LinkedHashSet是一个有序的集合:存储和取出的顺序相同。因为,它是一个双向链表,专门有一条用来记录顺序。

(2)底层使用数组加链表和一个记录顺序的链表、线程不安全的集合。

(3)默认初始容量为16,默认加载因子为0.75。

 

四、TreeSet类

TreeSet中如果存放的是字符串,会自动进行一个升序排序。因为字符串中实现了Comparable接口,并重写了compareTo方法。

我们可以通过自定义规则,让TreeSet来帮我们进行排序。

如果我们要使用TreeSet进行排序,那么我们的自定义类需要实现Comparable接口,并重写compareTo( )方法。

例:创建学生类并根据学生年龄进行排序

public class TreeDemo {		public static void main(String[] args) {		Student stu = new Student("张三", 18);		Student stu1 = new Student("李四", 12);		Student stu2 = new Student("王五", 20);		Set
set = new TreeSet
(); set.add(stu); set.add(stu1); set.add(stu2); for (Student student : set) { System.out.println(student); } }}class Student implements Comparable
{ private String name; private int age; public Student(String name, int age) { this.name = name; this.age = age; } @Override public int compareTo(Student o) { return this.age - o.age; } @Override public String toString() { return "Student [name=" + name + ", age=" + age + "]"; } }

结果:升序排序

Student [name=李四, age=12]

Student [name=张三, age=18]
Student [name=王五, age=20]

实现原理:

compareTo返回值是int类型。

如果返回的是负数,那么表示本对象小于传入的对象,是升序。

如果返回的是正数,那么表示本对象大于传入的对象,是降序。

所以,可以通过交换本对象与传入对象的位置,进行升,降设置

转载地址:http://iddlf.baihongyu.com/

你可能感兴趣的文章
(PAT 1080) Graduate Admission (排序)
查看>>
Play on Words UVA - 10129 (欧拉路径)
查看>>
mininet+floodlight搭建sdn环境并创建简答topo
查看>>
【UML】《Theach yourself uml in 24hours》——hour2&hour3
查看>>
【linux】nohup和&的作用
查看>>
【UML】《Theach yourself uml in 24hours》——hour4
查看>>
Set、WeakSet、Map以及WeakMap结构基本知识点
查看>>
【NLP学习笔记】(一)Gensim基本使用方法
查看>>
【NLP学习笔记】(二)gensim使用之Topics and Transformations
查看>>
【深度学习】LSTM的架构及公式
查看>>
【深度学习】GRU的结构图及公式
查看>>
【python】re模块常用方法
查看>>
【JavaScript】call()和apply()方法
查看>>
【JavaScript】箭头函数与普通函数的区别
查看>>
前端面试题
查看>>
【JavaScript】常用方法记录
查看>>
C++ 数据存储类型
查看>>
39. Combination Sum
查看>>
剑指Offer 1.二维数组中的查找
查看>>
剑指offer 2.重建二叉树
查看>>