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&nbsp;?&nbsp;e2==null&nbsp;:&nbsp;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的更多相关文章

  1. HashSet源码分析

    在java集合中有一种集合Set(集),他有两个实现类,分别是HashSet,TreeSet.下面仔细分析HashSet源码. 看了HashSet的源码就会发现HashSet的底层实现是利用HashM ...

  2. 死磕 java集合之HashSet源码分析

    问题 (1)集合(Collection)和集合(Set)有什么区别? (2)HashSet怎么保证添加元素不重复? (3)HashSet是否允许null元素? (4)HashSet是有序的吗? (5) ...

  3. 【Java入门提高篇】Day26 Java容器类详解(八)HashSet源码分析

    前面花了好几篇的篇幅把HashMap里里外外说了个遍,大家可能对于源码分析篇已经讳莫如深了.别慌别慌,这一篇来说说集合框架里最偷懒的一个家伙——HashSet,为什么说它是最偷懒的呢,先留个悬念,看完 ...

  4. HashSet源码分析:JDK源码系列

    1.简介 继续分析源码,上一篇文章把HashMap的分析完毕.本文开始分析HashSet简单的介绍一下. HashSet是一个无重复元素集合,内部使用HashMap实现,所以HashMap的特征耶继承 ...

  5. java.util.HashSet源码分析

    public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, java. ...

  6. JAVA的HashSet源码分析

    一.HashSet概述 HashSet实现Set接口,由哈希表(实际上是一个HashMap实例)支持.它不保证set的迭代顺序:特别是它不保证该顺序恒久不变.此类允许使用null元素. 二.HashS ...

  7. Java集合之HashSet源码分析

    概述 HashSet是基于HashMap来实现的, 底层采用HashMap的key来保存数据, 借此实现元素不重复, 因此HashSet的实现比较简单, 基本上的都是直接调用底层HashMap的相关方 ...

  8. HashSet源码分析 jdk1.6

    Set的特点:Set元素无顺序,且元素不可以重复. 1.定义 public class HashSet<E> extends AbstractSet<E> implements ...

  9. HashSet源码分析1

    import java.util.HashSet; import java.util.Iterator; import java.util.Set; public class SetTest { pu ...

随机推荐

  1. Mac下部署与启动STF

    一.stf在Mac下的部署1.安装Java及jdk可自己谷歌(如果不能自建云梯)2.安装nodejs包(我是直接在官网下载的LTS版本) • Node.js v8.12.0 to /usr/local ...

  2. Node.js——render封装

    封装 挂在到res上

  3. txt通过 vb编程导入 excel

    Private Sub CommandButton1_Click() '按钮触发, '按钮触发,目前支持ASNI文本的数据, 单行 fileToOpen = Application.GetOpenFi ...

  4. 【转】Web 前沿——HTML5 Form Data 对象的使用

    XMLHttpRequest Level 2 添加了一个新的接口——FormData.利用 FormData 对象,我们可以通过 JavaScript 用一些键值对来模拟一系列表单控件,我们还可以使用 ...

  5. python 实现代理服务器

    # encoding:utf-8 import socket import thread import re def getAddr(d): a = re.search("Host: (.* ...

  6. Java集合(二)--Iterator和Iterable

    Iterable: public interface Iterable<T> { Iterator<T> iterator(); } 上面是Iterable源码,只有一个ite ...

  7. spark版本不支持(降版本打包)

    在做项目的时候代码已经更新为hadoop 2.7  spark 2.1 scala 2.11.8版本,但是服务器版本使用的是hadoop2.6 spark1.6 以及scala2.10.6版本,,主程 ...

  8. IO 双引号 输出 输入

    #! /usr/bin/perl use strict;use warnings; print "\n---------<STDIN>_store_into_an_array_a ...

  9. BZOJ1079: [SCOI2008]着色方案 (记忆化搜索)

    题意:有n个木块排成一行,从左到右依次编号为1~n.你有k种颜色的油漆,其中第i种颜色的油漆足够涂ci个木块. 所有油漆刚好足够涂满所有木块,即c1+c2+...+ck=n.相邻两个木块涂相同色显得很 ...

  10. linux如何正确设置静态ip

    如果是新安装的CentOS7的用户,刚开始应该是没网的,ifconfig命令在CentOS7已经被淘汰了. 1.使用ip addr 即查看分配网卡情况. 2.激活网卡 [root@localhost ...