Java 哈希表


哈希表

  • 哈希表是 HashSet 和 HashMap 集合存储数据的结构;
  • 在 JDK1.8 之前,哈希表底层采用数组 + 链表实现,即使用数组处理冲突,同一 hash 值的链表都存储在一个数组里,可见哈希值不唯一,不同元素可以有相同的哈希值。但是当位于一个桶中的元素较多,即 hash 值相等的元素较多时,通过 key 值依次查找的效率较低。到了 JDK 1.8(即 Java 8.0 或 JDK 8),哈希表存储采用数组 + 链表 + 红黑树实现,当链表长度超过阈值 8 时,将链表转换为红黑树,这样大大减少了查找时间;
  • 简单的来说,哈希表是由数组+链表+红黑树(JDK 1.8 增加了红黑树部分)实现的,如下图所示:

哈希表


1. 在 HashSet 上的实现逻辑图

  • JDK1.8 引入红黑树大程度优化了 HashMap 的性能,那么对于我们来讲保证 HashSet 集合元素的唯一,其实就是根据对象的 hashCode() 和 equals() 方法来决定的。如果我们往集合中存放自定义的对象,那么保证其唯一,就必须复写 hashCode() 和 equals() 方法建立属于当前对象的比较方式;

哈希表在 HashSet 上的具体体现


2. 在 HashSet 上的 Java 实现

  • 给 HashSet 中存放自定义类型元素时,需要重写对象中的 hashCode() 和 equals() 方法,建立自己的比较方式,才能保证 HashSet 集合中的对象唯一;
import java.util.HashSet;
import java.util.Objects;

class Student {
    private String name;
    private int age;

    public Student(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;
        Student student = (Student) o;
        return age == student.age &&
                Objects.equals(name, student.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }

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

public class test {
    public static void main(String[] args) {
        //创建集合对象   该集合中存储 Student类型对象
        HashSet<Student> stuSet = new HashSet<Student>();
        //存储
        Student stu = new Student("于谦", 43);
        stuSet.add(stu);
        stuSet.add(new Student("郭德纲", 44));
        stuSet.add(new Student("于谦", 43));
        stuSet.add(new Student("郭麒麟", 23));
        stuSet.add(stu);

        for (Student stu2 : stuSet) {
            System.out.println(stu2);
        }
    }
}
/*
输出
Student{name='郭德纲', age=44}
Student{name='于谦', age=43}
Student{name='郭麒麟', age=23}
 */
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值