OddFar's Notes OddFar's Notes
首页
  • Java-Se

    • Java基础
    • Java面向对象
    • Java常用类
    • Java集合框架
  • Java-Se进阶

    • JUC多线程
  • Java-ee

    • JavaWeb
  • SQL 数据库

    • MySQL
  • NoSQL 数据库

    • Redis
    • ElasticSearch
    • MongoDB
  • 数据库

    • MyBatis
    • MyBatis-Plus
  • Spring

    • Spring
  • 中间件

    • RabbitMQ
  • Git
  • Docker
  • Jenkins
爬虫
  • Campus (opens new window)
  • 校园信息墙 (opens new window)
关于
归档
GitHub (opens new window)
首页
  • Java-Se

    • Java基础
    • Java面向对象
    • Java常用类
    • Java集合框架
  • Java-Se进阶

    • JUC多线程
  • Java-ee

    • JavaWeb
  • SQL 数据库

    • MySQL
  • NoSQL 数据库

    • Redis
    • ElasticSearch
    • MongoDB
  • 数据库

    • MyBatis
    • MyBatis-Plus
  • Spring

    • Spring
  • 中间件

    • RabbitMQ
  • Git
  • Docker
  • Jenkins
爬虫
  • Campus (opens new window)
  • 校园信息墙 (opens new window)
关于
归档
GitHub (opens new window)
  • java-基础

  • java-面向对象

  • Java-常用类

  • Java-集合框架

    • 集合概序
    • ArrayList
    • LinkedList
    • Vevtor和Stack
    • List总结
    • HashMap
    • set
    • HashSet
      • HashSet
        • 存储规则
        • HashSet用处
        • LinkedHashSet
    • TreeSet
    • 迭代器
    • 泛型
    • Collections工具类
  • Java-多线程

  • JavaWeb

  • Java
  • Java-集合框架
zhiyuan
2021-04-16
目录

HashSet

# HashSet

HashSet是一个没有重复元素的集合,它其实是由HashMap实现的,HashMap保存的是建值对,然而我们只能向HashSet中添加Key,原因在于HashSet的Value其实都是同一个对象,这是HashSet添加元素的方法,可以看到辅助实现HashSet的map中的value其实都是Object类的同一个对象。

特点:

  • 底层数据结构是哈希表
  • 对集合的迭代顺序不作任何保证,也就是说不保证存储和取出的元素顺序一致
  • 没有带索引的方法,所以不能使用普通for循环遍历
  • 由于是Set集合,所以是不包含重复元素的集合

# 存储规则

**哈希表边存放的是哈希值。**HashSet存储元素的顺序并不是按照存入时的顺序(和List显然不同) 是按照哈希值来存的所以取数据也是按照哈希值取得。

HashSet不存入重复元素的规则.使用hashcode和equals

由于Set集合是不能存入重复元素的集合。那么HashSet也是具备这一特性的。HashSet如何检查重复?HashSet会通过元素的hashcode()和equals方法进行判断元素师否重复。

当你试图把对象加入HashSet时,HashSet会使用对象的hashCode来判断对象加入的位置。同时也会与其他已经加入的对象的hashCode进行比较,如果没有相等的hashCode,HashSet就会假设对象没有重复出现。

简单一句话,如果对象的hashCode值是不同的,那么HashSet会认为对象是不可能相等的。

因此我们自定义类的时候需要重写hashCode,来确保对象具有相同的hashCode值。

如果元素(对象)的hashCode值相同,是不是就无法存入HashSet中了?当然不是,会继续使用equals 进行比较。如果 equals为true 那么HashSet认为新加入的对象重复了,所以加入失败。如果equals 为false那么HashSet 认为新加入的对象没有重复,新元素可以存入。

总结:

元素的哈希值是通过元素的hashcode方法来获取的, HashSet首先判断两个元素的哈希值,如果哈希值一样,接着会比较equals方法 如果 equls结果为true ,HashSet就视为同一个元素。如果equals 为false就不是同一个元素。

哈希值相同equals为false的元素是怎么存储呢,就是在同样的哈希值下顺延(可以认为哈希值相同的元素放在一个哈希桶中)。也就是哈希一样的存一列。 image-20210331235903905

# HashSet用处

问题:现在有一批数据,要求不能重复存储元素,而且要排序。ArrayList 、 LinkedList不能去除重复数据。HashSet可以去除重复,但是是无序。

所以这时候就要使用TreeSet了

案例:创建一个学生类,并重写equals和hashcode

import java.util.Objects;

public class HashSetStudent {
    public String name;
    public int age;

    public HashSetStudent(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        HashSetStudent that = (HashSetStudent) o;
        return age == that.age && Objects.equals(name, that.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

代码:

public class HashSetTest {
    public static void main(String[] args) {
        HashSetStudent s1 = new HashSetStudent("李白1",15);
        HashSetStudent s2 = new HashSetStudent("李白2",16);

        HashSetStudent s3 = new HashSetStudent("李白1",15);//重复值不插入
        
        HashSetStudent s4 = new HashSetStudent("李白1",10);
        HashSetStudent s5 = new HashSetStudent("李白2",10);

        HashSet<HashSetStudent> hs = new HashSet<>();
        hs.add(s1);
        hs.add(s2);
        hs.add(s3);
        hs.add(s4);
        hs.add(s5);

        for(HashSetStudent S:hs){
            System.out.println(S.name+"--"+S.age);
        }

    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

最后输出:

李白2--10 李白1--10 李白1--15 李白2--16

# LinkedHashSet

特点:

  • 哈希表和链表实现的Set接口,具有可预测的迭代次序
  • 由链表保证元素有序,也就是说元素的存储和取出顺序是一致的
  • 由哈希表保证元素唯一,也就是说没有重复的元素

待补充......

在 GitHub 上编辑此页 (opens new window)
最后更新: 2023/03/26, 13:03:00
set
TreeSet

← set TreeSet→

Theme by Vdoing | Copyright © 2021-2023 oddfar | 冀ICP备20001094号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式