HashSet源码分析2
package com.test1; import java.util.HashSet;
import java.util.Iterator;
import java.util.Set; public class SetTest {
public static void main(String[] args) {
/*
* Set<String> set = new HashSet<>();
* System.out.println(set.add("abc"));
* System.out.println(set.add("xyz"));
* System.out.println(set.add("abc"));
*
* for (Iterator<String> it = set.iterator(); it.hasNext();) {
* System.out.println(it.next()); }
*/
/*
* String a = "abc"; String b = "abc"; System.out.println(a.hashCode());
* System.out.println(b.hashCode());
*/
Set<People> set2 = new HashSet<>();
set2.add(new People("zhangsan"));
set2.add(new People("lisi"));
set2.add(new People("zhangsan"));
for (Iterator<People> it = set2.iterator(); it.hasNext();) {
System.out.println(it.next().getName());
}
}
} class People {
String name; public People(String name) {
this.name = name;
} public String getName() {
return this.name;
} @Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof People) {
People people = (People) obj;
if(this.name.equals(people.getName()));
return true;
}
return false;
}
@Override
public int hashCode() {
return this.name.hashCode();
}
}
我们来看HashSet的构造方法:
/**
* Constructs a new, empty set; the backing <tt>HashMap</tt> instance has
* default initial capacity (16) and load factor (0.75).
*/
public HashSet() {
map = new HashMap<>();
}
竟然是new HashMap<>();
关于HashSet与HashMap之间的关系:
HashSet是由HashMap来实现的。HashSet里面的几乎所有的方法都是由HashMap实现的
这个HashMap的key就是放进HashSet中的对象,value就是一个Object类型的对象,当调用HashSet的add方法时,实际上是向HashMap中增加了一行(key-value对),该key就是向HashSet中增加的那个对象,该行的value就是一个Object类型的对象。HashMap底层采用数组维护(数组中每个元素都是一个Map.Entry对象),调用增加的那个对象的hashCode方法,得到一个hashCode值,然后根据该值计算出一个数组的下标索引(计算出数组中的一个位置),将准备添加到Map中的对象与该位置处的对象进行比较(equals方法),如果相同,那么就向该位置处的那个对象(Map.Entry类型)的value值替换掉,否则沿着该Entry链继续重复上述过程,如果链的最后依然没有找到相同的对象,那么这个时候就将该对象添加到数组中,将数组中该位置处的Entry对象链接到这个对象后面:对于HashSet与HashMap来说,这样做是为了提高查找的效率,使得查找时间不随着Set或Map的大小而改变。
查看add方法
/**
* Adds the specified element to this set if it is not already present.
* More formally, adds the specified element <tt>e</tt> to this set if
* this set contains no element <tt>e2</tt> such that
* <tt>(e==null ? e2==null : e.equals(e2))</tt>.
* If this set already contains the element, the call leaves the set
* unchanged and returns <tt>false</tt>.
*
* @param e element to be added to this set
* @return <tt>true</tt> if this set did not already contain the specified
* element
*/
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
HashSet源码分析2的更多相关文章
- HashSet源码分析
在java集合中有一种集合Set(集),他有两个实现类,分别是HashSet,TreeSet.下面仔细分析HashSet源码. 看了HashSet的源码就会发现HashSet的底层实现是利用HashM ...
- 死磕 java集合之HashSet源码分析
问题 (1)集合(Collection)和集合(Set)有什么区别? (2)HashSet怎么保证添加元素不重复? (3)HashSet是否允许null元素? (4)HashSet是有序的吗? (5) ...
- 【Java入门提高篇】Day26 Java容器类详解(八)HashSet源码分析
前面花了好几篇的篇幅把HashMap里里外外说了个遍,大家可能对于源码分析篇已经讳莫如深了.别慌别慌,这一篇来说说集合框架里最偷懒的一个家伙——HashSet,为什么说它是最偷懒的呢,先留个悬念,看完 ...
- HashSet源码分析:JDK源码系列
1.简介 继续分析源码,上一篇文章把HashMap的分析完毕.本文开始分析HashSet简单的介绍一下. HashSet是一个无重复元素集合,内部使用HashMap实现,所以HashMap的特征耶继承 ...
- java.util.HashSet源码分析
public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, java. ...
- JAVA的HashSet源码分析
一.HashSet概述 HashSet实现Set接口,由哈希表(实际上是一个HashMap实例)支持.它不保证set的迭代顺序:特别是它不保证该顺序恒久不变.此类允许使用null元素. 二.HashS ...
- Java集合之HashSet源码分析
概述 HashSet是基于HashMap来实现的, 底层采用HashMap的key来保存数据, 借此实现元素不重复, 因此HashSet的实现比较简单, 基本上的都是直接调用底层HashMap的相关方 ...
- HashSet源码分析 jdk1.6
Set的特点:Set元素无顺序,且元素不可以重复. 1.定义 public class HashSet<E> extends AbstractSet<E> implements ...
- HashSet源码分析1
import java.util.HashSet; import java.util.Iterator; import java.util.Set; public class SetTest { pu ...
随机推荐
- js基础 -----鼠标事件(按下 拖拽)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- PHP(二)常用函数
数学函数 数组函数 字符串函数
- PAT甲级考前整理(2019年3月备考)之三,持续更新中.....
PAT甲级考前整理一:https://www.cnblogs.com/jlyg/p/7525244.html,主要讲了131题的易错题及坑点 PAT甲级考前整理二:https://www.cnblog ...
- Java语法基础-static关键字
static关键字说明 “static方法就是没有this的方法.在static方法内部不能调用非静态方法,反过来是可以的.而且可以在没有创建任何对象的前提下,仅仅通过类本身来调用static方法.这 ...
- markdown表格中怎么插入逻辑或符号|?
| 73向下投票接受 | 如果你删除反引号(****),使用|`黑客作品 a | r ------------|----- `a += x;` | r1 a |= y; | r2 并产生以下输出 在这 ...
- Java.io.ObjectOutputStream.writeObject()方法实例
java.io.ObjectOutputStream.writeObject(Object obj) 方法将指定对象写入ObjectOutputStream.该对象的类,类的签名,以及类及其所有超类型 ...
- Ubuntu 下更新或下载输入法(搜狗)
ubuntu12.04的fcitx版本不支持,不满足依赖,需要更新fcitx 添加fcitx源添加fcitx源命令 : sudo add-apt-repository ppa:fcitx-team/n ...
- C#override与new修饰隐藏的区别(转载)
C#比java多一个new隐藏的功能.C# override重写相当于java中没有关键字的方法重写.所以java中方法是没有隐藏功能的. C# override重写,是指对父类中的虚方法(标记vir ...
- 09CSS高级定位
CSS高级定位 定位方式——position position:static|absolute|relative static表示为静态定位,是默认设置. absolute表示绝对定位,与下位置属 ...
- 布尔上下文,这里misreading返回的是来源列表中元素的个数,如果列表中2个值都是undef,则列表元素个数是1: while( $misreading = (my $test_consideration, my $english_pragma) = each %map_function){
布尔上下文,这里misreading返回的是来源列表中元素的个数, 列表赋值运算的值将会是来源列表中元素的个数,空列表表示0,如果列表中2个值都是undef,则列表元素个数是1 布尔上下文,这里mis ...