2021.10.29 写于山威
没有学过UML,自己瞎画的
我们都知道,在java的set中是不能出现重复的元素的,但是是如何保证这一问题的实现的呢?我们先买个关子,我们先想想,平时我们如何判断元素是否相等:
所以我们一般都会理所应当的想到,在set中要满足插入元素没有重复的时候,一般是使用集合元素的equals方法来判断的,那么我们下面来写一段代码检测一下
//只是重写equals方法 public static class A { @Override public boolean equals(Object obj) { return true; } } //只是重写hashcode方法 public static class B { @Override public int hashCode() { return 1; } } //将equals方法和hashcode方法都重写 public static class C { public boolean equals(Object obj) { return true; } @Override public int hashCode() { return 2; } } public static void main( String [] __) { //我们写了三个私有类,接下来我们测试一下 HashSet<Object> test=new HashSet<Object>(); test.add(new A()); test.add(new A()); test.add(new B()); test.add(new B()); test.add(new C()); test.add(new C()); //我们重复的加进去了六个元素,那么按照我们重写之后的方法(无论是什么都返回true与相同的hashcode) //这个set里面目前还有谁在保留呢? System.out.println(test); }
在这种情况下,大家猜测会输出什么呢?
[mytestDemo.Hello$B@1, mytestDemo.Hello$B@1, mytestDemo.Hello$C@2, mytestDemo.Hello$A@7de26db8, mytestDemo.Hello$A@1175e2db]
这是我的输出,可以很明显的看到,输出里面有两个A,两个B,但是只有一个C,原因其实很简单,因为重写方法的时候,我们只有对于C既重写hashcode,又重写了equals
因此我们可以得到,set判断元素是否重复的时候,既使用了hashcode,又使用equals方法,具体是怎么使用,让我们进入源码看看(稍稍看看,深入看不能我能窥探的)
我们可以看到,在hashset中是有一个hashmap来保证插入的元素是不会重复的(这一点我也没有想到)
具体这里的put方法中有一个参数是hash(value),我们可以看到在这个函数里面其实就是调用了对象的hashcode函数,用得到的这个函数去检索set集合中相应位置是否有元素(set说是无序,其实内部是使用hashcode作为序的),因此会有下面的几种情况
下面我来画图让大家看的更加直观,对于刚刚的插入:
大概的讲解就是这么多了,我知识水平有限....