类HashSet

 简介

java.util.HashSet 是 Set 接口的一个实现类, java.util.HashSet 底层的实现其实是一个 java.util.HashMap 支持。 

HashSet特点:

  • 不允许存储重复的元素
  • 没有索引,也就没有带索引的方法。因此不能使用for循环遍历
  • 无序集合。元素都是无序的(即存取顺序不一致)。
  • 底层是一个哈希表结构(查询的速度非常快)

哈希值

一个十进制的整数,由系统随机给出(就是对象的地址值, 是一个逻辑地址, 是模拟出来得到的地址,不是数据实际存储的物理地址)。

Object类中有一个方法int hashCode() 返回对象的哈希码值。获取对象的哈希值。

HashSet集合存储数据的结构(哈希表)

什么是哈希表呢?
在JDK1.8之前,哈希表底层采用数组+链表实现,即使用链表处理冲突,同一hash值的链表都存储在一个链表里。但是当位于一个桶中的元素较多,即hash值相等的元素较多时,通过key值依次查找的效率较低。而JDK1.8中,哈希表存储采用数组+链表+红黑树实现,当链表长度超过阈值(8)时,将链表转换为红黑树,这样大大减少了查找时间。简单的来说,哈希表是由数组+链表+红黑树(JDK1.8增加了红黑树部分)实现的,

HashSet存储元素不重复的原理

其实就是根据对象的hashCode和equals方法来决定的。如果我们往集合中存放自定义的对象,那么保证其唯一,就必须复写hashCode和equals方法建立属于当前对象的比较方式。
详细来说:

当我们调用add方法往集合中,存储元素的时候。程序的执行流程

  1. add方法会调用要添加的元素的hashCode方法,计算机元素的哈希值。
  2. 在集合中查找有没有此元素的哈希值,发现没有就会把集合添加到元素中去
  3. 如果有(哈希冲突)。叫使用equals方法让2个元素进行比较,如果返回值为true,认定两个元素相同,不会存储到集合中去。
  4. 如果equals方法的返回值为false ,认为两元素不同,则会存储到集合中。

代码举例:

package demo02;

import java.util.Objects;

// 定义测试用对象
public class Student {
    private String name;
    private int age;

    // 全参数构造
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // 无参数构造
    public Student() {
    }

    //重写toString方法
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

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

    //重写hashCode
    @Override
    public int hashCode() {

        return Objects.hash(name, age);
    }
}

测试代码

package demo02;

import java.util.HashSet;

public class HashSetTest {
    public static void main(String[] args) {
        // 创建集合,存储自定义类型
        HashSet hashSet = new HashSet();
        // 年龄和姓名相同看做同一个人
        hashSet.add(new Student("张三", 18));
        hashSet.add(new Student("张四", 18));
        hashSet.add(new Student("张三", 18));
        hashSet.add(new Student("张无", 18));
        hashSet.add(new Student("张三", 18));
        // 查看集合中存储的元素
        System.out.println(hashSet);
    }
}

执行结果

LinkedHashSet

我们知道HashSet保证元素唯一,可是元素存放进去是没有顺序的,那么我们要保证有序,怎么办呢?在HashSet下面有一个子类 java.util.LinkedHashSet ,它是链表和哈希表组合的一个数据存储结构。

猜你喜欢

转载自www.cnblogs.com/wurengen/p/10788234.html
今日推荐