HashSet的存储机制

简介:     Java中Set接口下的HashSet类是一个存储不可重复数据的集合,可是我们在用的时候往往发现,明明看似重复的数据,HashSet仍然存储了进去,这不免让我们感到疑惑,不是说存储不可重复的数据的吗?下面通过实验一步一步搞懂HashSet的存储机制。

    Java中Set接口下的HashSet类是一个存储不可重复数据的集合,可是我们在用的时候往往发现,明明看似重复的数据,HashSet仍然存储了进去,这不免让我们感到疑惑,不是说存储不可重复的数据的吗?下面通过实验一步一步搞懂HashSet的存储机制。

  1、假设有以下类

   public class Student {
	String  stuName;
	
	public Student() {
		// TODO Auto-generated constructor stub
	}
	public Student(String s){
		this.stuName = s;
	}
	public String getStu(){
		return this.stuName;
	}
   }
  2、在test类中主函数中写入如下代码
            Set<Student>  testSet = new HashSet<Student>();
        Student s1 = new Student("stu1");
        Student s2 =new Student("stu1");
        Student s3 =new Student("stu2");
        testSet.add(s1);
        testSet.add(s2);
        testSet.add(s3);
        Iterator<Student> it = testSet.iterator();
        while(it.hasNext()){
             Student tempStu =it.next();
             System.out.println(tempStu.getStu());
        }
   Eclipse中的输出为  stu1,stu1,stu2

   

大家会说,当然了,因为Student类没有比较嘛,下面我们在Student类中重写Object的equals方法

        @Override
	public boolean equals(Object obj) {
		// TODO Auto-generated method stub
		Student s =(Student)obj;
		return this.stuName.equals(s.getStu());
	}
仍然是输出三个结果,通过观察Object类的方法,我们发现一个hashCode()方法,HashSet会不会跟这个方法有点关系呢?下面重写这个方法。

        @Override
	public int hashCode() {
		// TODO Auto-generated method stub
		if(stuName=="stu1")
			return 1;
		else {
			return super.hashCode();
		}
	}
Eclipse的输出为stu1 ,stu2


通过给stuName为stu1的Student对象的hashCode赋值为相同的1,我们得到的输出是一个stu1,满足了存储不可重复的目的。下面我们做个有趣的事情。将上面重写的equals方法改为如下代码。

        @Override
	public boolean equals(Object obj) {
		// TODO Auto-generated method stub
		return false;
	}
输出  stu1,stu2,stu1

通过给equals方法重写,使其始终返回false,导致即使两个stu1的hashCode相同,仍然可以插入,至此,我们明白了HashSet的存储机制。

HashSet在存一个新的对象的时候,先比较其跟已有的对象中的hashCode是否有相同的,如果没有相同的,则直接添加,不会调用equals方法进行判断,所以导致即使我们重写了equals方法也无法避免重复值的插入,只有当有两个hashCode相同的时候,它才会调用equals方法进行比较,如果返回的是true,则不添加,如果返回false,则添加进集合,所以在最后我们给定stu1的hashCode为1的时候,因为equals始终返回false,所有两个stu1均存到了集合中。


至此,我们搞清楚了HashSet的存储机制,但对于hashCode方法的重写,又会使得我们头疼了,如何使属性相同的hashCode不同呢?好在有Eclipse帮助我们,只要在Student类中右击->source->重写hashCode方法和equals方法,在弹出的窗口中选择相关属性即可,作为小白的我,不得不感叹Eclipse的伟大之处

目录
相关文章
|
存储 算法 Java
HashMap 之底层数据结构和扩容机制
HashMap 之底层数据结构和扩容机制
976 1
|
2月前
|
存储 Java
深入探讨了Java集合框架中的HashSet和TreeSet,解析了两者在元素存储上的无序与有序特性。
【10月更文挑战第16天】本文深入探讨了Java集合框架中的HashSet和TreeSet,解析了两者在元素存储上的无序与有序特性。HashSet基于哈希表实现,添加元素时根据哈希值分布,遍历时顺序不可预测;而TreeSet利用红黑树结构,按自然顺序或自定义顺序存储元素,确保遍历时有序输出。文章还提供了示例代码,帮助读者更好地理解这两种集合类型的使用场景和内部机制。
48 3
|
1月前
|
存储 Java Serverless
HashMap的底层数据结构是怎样的
在Java中,HashMap是一种基于哈希表的Map接口实现,以其高效的数据存取能力而广泛使用。本文将深入探讨HashMap的底层数据结构,揭示其如何通过数组、链表和红黑树的结合来优化性能。
|
1月前
|
存储 Java Serverless
深入探索:HashMap的底层数据结构揭秘
HashMap作为Java中一个非常重要的集合类,其底层数据结构的设计对于性能有着至关重要的影响。本文将详细解析HashMap的底层数据结构,帮助开发者更好地理解和使用这一强大的工具。
30 7
|
1月前
|
存储 Java Serverless
HashMap的底层数据结构
HashMap作为Java中一个核心的数据结构,以其高效的键值对存储和检索能力而被广泛使用。本文将深入探讨HashMap的底层数据结构,揭示其如何通过精巧的设计实现快速的数据访问。
30 6
|
1月前
|
存储 Java
HashMap的底层数据结构详解
在Java中,HashMap 是一个非常重要的集合类,用于存储键值对(Key-Value)。它提供了快速的数据插入、删除和查找功能。本文将深入探讨 HashMap 的底层数据结构,帮助读者更好地理解其工作原理。
|
2月前
|
存储 算法 Java
Set接口及其主要实现类(如HashSet、TreeSet)如何通过特定数据结构和算法确保元素唯一性
Java Set因其“无重复”特性在集合框架中独树一帜。本文解析了Set接口及其主要实现类(如HashSet、TreeSet)如何通过特定数据结构和算法确保元素唯一性,并提供了最佳实践建议,包括选择合适的Set实现类和正确实现自定义对象的hashCode()与equals()方法。
45 4
|
2月前
|
存储 安全 数据库
除了 HashMap,还有哪些数据结构可以实现键值对存储?
【10月更文挑战第11天】 除了`HashMap`,其他常见支持键值对存储的数据结构包括:`TreeMap`(基于红黑树,键有序)、`LinkedHashMap`(保留插入顺序)、`HashTable`(线程安全)、`B-Tree`和`B+Tree`(高效存储大量数据)、`SkipList`(通过跳跃指针提高查找效率)及`UnorderedMap`(类似`HashMap`)。选择合适的数据结构需根据排序、并发、存储和查找性能等需求。
|
2月前
|
存储 缓存 索引
从底层数据结构和CPU缓存两方面剖析LinkedList的查询效率为什么比ArrayList低
本文详细对比了ArrayList和LinkedList的查询效率,从底层数据结构和CPU缓存两个方面进行分析。ArrayList基于动态数组,支持随机访问,查询时间复杂度为O(1),且CPU缓存对其友好;而LinkedList基于双向链表,需要逐个节点遍历,查询时间复杂度为O(n),且CPU缓存对其帮助不大。文章还探讨了CPU缓存对数组增删操作的影响,指出缓存主要作用于读取而非修改。通过这些分析,加深了对这两种数据结构的理解。
50 2
|
3月前
|
存储 算法 Java
深入剖析HashMap:理解Hash、底层实现与扩容机制
【9月更文挑战第6天】在Java编程中,`HashMap`是一个常用的数据结构,其高效性和可靠性依赖于深入理解哈希、底层实现及扩容机制。哈希通过散列算法将键映射到数组索引,采用链表或红黑树处理冲突;底层实现结合数组与链表,利用2的幂次方长度加快定位;扩容机制在元素数量超过负载因子与数组长度乘积时触发,通过调整初始容量和负载因子可优化性能。
118 3