HashSet 实现类
HashSet 实现类
通过 HashCode 判断元素是否存在,若存在则不添加,否则添加以此实现唯一性
常用方法
| Modifier and Type | Method and Description |
|---|---|
boolean |
add(E e) 将指定的元素添加到此集合(如果尚未存在)。 |
void |
clear() 从此集合中删除所有元素。 |
Object |
clone() 返回此 HashSet实例的浅层副本:元素本身不被克隆。 |
boolean |
contains(Object o) 如果此集合包含指定的元素,则返回 true 。 |
boolean |
isEmpty() 如果此集合不包含元素,则返回 true 。 |
Iterator<E> |
iterator() 返回此集合中元素的迭代器。 |
boolean |
remove(Object o) 如果存在,则从该集合中删除指定的元素。 |
int |
size() 返回此集合中的元素数(其基数)。 |
Spliterator<E> |
spliterator() 在此集合中的元素上创建late-binding和故障快速 Spliterator 。 |
演示
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class SetDemo {
public static void main(String[] args) {
HashSet<String> test = new HashSet<>();
test.add("华为");
test.add("苹果");
test.add("小米");
System.out.println(test.size());
System.out.println(test);
//添加重复元素不会进行添加
test.add("华为");
System.out.println(test);
//删除元素,由于 Set 集合没有下标,只能指定值进行删除
test.remove("华为");
System.out.println(test);
//再次添加进来是无序的
test.add("华为");
//集合的遍历
System.out.println("-----for------");
for (String string : test) {
System.out.println(string);
}
System.out.println("-----Iterator-----");
Iterator<String> it = test.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
}
}
重写 hashcode equals 方法
注:可以通过系统根据自动重写这两个方法
存储方式
- 根据元素的
hashcode方法计算存储位置,若该位置不存在元素则直接储存,否则进入下一步 - 再执行
equals方法,若返回值为true则认为元素重复;否则形成链表

未重写方法时
import java.util.HashSet;
public class HashDemo {
private String name;
private int age;
public HashDemo(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "HashDemo [name=" + name + ", age=" + age + "]";
}
public static void main(String[] args) {
HashSet<HashDemo> hash = new HashSet<>();
HashDemo h1 = new HashDemo("张三", 20);
HashDemo h2 = new HashDemo("李四", 21);
HashDemo h3 = new HashDemo("王五", 22);
hash.add(h1);
hash.add(h2);
hash.add(h3);
System.out.println(hash.size());
System.out.println(hash);
//添加同一个对象将会被equals判别为true,将不会将此对象进行再次添加
hash.add(h1);
System.out.println(hash.size());
System.out.println(hash);
//但是对于相同的值的不同对象,却能够添加
hash.add(new HashDemo("张三", 20));
System.out.println(hash.size());
System.out.println(hash);
}
}
未对方法进行重写之前,对于用于相同数值的不同对象依然能够进行添加,这样不符合不重复的法则,因此对方法进行重写,重写后代码如下
只对 hanshcode 进行重写后的代码如下
import java.util.HashSet;
public class HashDemo {
private String name;
private int age;
public HashDemo(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "HashDemo [name=" + name + ", age=" + age + "]";
}
//重写hashcode方法使hashcode只与姓名和年龄有关
@Override
public int hashCode() {
int n1 = this.name.hashCode();
int n2 = this.age;
return n1 + n2;
}
public static void main(String[] args) {
HashSet<HashDemo> hash = new HashSet<>();
HashDemo h1 = new HashDemo("张三", 20);
HashDemo h2 = new HashDemo("李四", 21);
HashDemo h3 = new HashDemo("王五", 22);
hash.add(h1);
hash.add(h2);
hash.add(h3);
System.out.println(hash.size());
System.out.println(hash);
//添加同一个对象将会被equals判别为true,将不会将此对象进行再次添加
hash.add(h1);
System.out.println(hash.size());
System.out.println(hash);
//但是对于相同的值的不同对象,却能够添加
hash.add(new HashDemo("张三", 20));
System.out.println(hash.size());
System.out.println(hash);
}
}
3
[HashDemo [name=王五, age=22], HashDemo [name=张三, age=20], HashDemo [name=李四, age=21]]
3
[HashDemo [name=王五, age=22], HashDemo [name=张三, age=20], HashDemo [name=李四, age=21]]
4
[HashDemo [name=王五, age=22], HashDemo [name=张三, age=20], HashDemo [name=张三, age=20], HashDemo [name=李四, age=21]]
依然能够添加值相同的元素,但是与未重写 hashcode 时的区别在于,新添加的元素没有放在数组中,由于其与 p1 拥有相同的 hashcode 因此新的元素和 p1 占用相同的位置,只是形成链表存储
如图

为不添加值相同的元素,因此再以上基础上还需对 equals 进行重写
import java.util.HashSet;
public class HashDemo {
private String name;
private int age;
public HashDemo(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "HashDemo [name=" + name + ", age=" + age + "]";
}
//重写hashcode方法使hashcode只与姓名和年龄有关
@Override
public int hashCode() {
int n1 = this.name.hashCode();
int n2 = this.age;
return n1 + n2;
}
//重写equals,当值相等时返回true
@Override
public boolean equals(Object obj) {
if(obj == null) {
return false;
}
if(this == obj) {
return true;
}
if(obj instanceof HashDemo) {
HashDemo h = (HashDemo)obj;
if(this.name.equals(h.name) && this.age == h.age) {
return true;
} else {
return false;
}
}
return false;
}
public static void main(String[] args) {
HashSet<HashDemo> hash = new HashSet<>();
HashDemo h1 = new HashDemo("张三", 20);
HashDemo h2 = new HashDemo("李四", 21);
HashDemo h3 = new HashDemo("王五", 22);
hash.add(h1);
hash.add(h2);
hash.add(h3);
System.out.println(hash.size());
System.out.println(hash);
//添加同一个对象将会被equals判别为true,将不会将此对象进行再次添加
hash.add(h1);
System.out.println(hash.size());
System.out.println(hash);
//但是对于相同的值的不同对象,却能够添加
hash.add(new HashDemo("张三", 20));
System.out.println(hash.size());
System.out.println(hash);
//hash.remove(new HashDemo("张三", 20)); 重写equals后可使用这种方式删除
}
}
3
[HashDemo [name=王五, age=22], HashDemo [name=张三, age=20], HashDemo [name=李四, age=21]]
3
[HashDemo [name=王五, age=22], HashDemo [name=张三, age=20], HashDemo [name=李四, age=21]]
3
[HashDemo [name=王五, age=22], HashDemo [name=张三, age=20], HashDemo [name=李四, age=21]]
可见,此时将不会添加相同的元素(对于人而言相同的)。
HashSet 实现类的更多相关文章
- HashSet<T>类 用法
HashSet<T>类主要是设计用来做高性能集运算的,例如对两个集合求交集.并集.差集等.集合中包含一组不重复出现且无特性顺序的元素 改变集的值的方法: HashSet<T>的 ...
- HashSet<T>类
HashSet<T>类主要是设计用来做高性能集运算的,例如对两个集合求交集.并集.差集等.集合中包含一组不重复出现且无特性顺序的元素. HashSet<T>的一些特性如下: 1 ...
- (转) C#解惑:HashSet<T>类
HashSet<T>是一个相对“冷门”的类型,平时在项目中用得不多,但是在特定的业务中可以大用. 先来了解下HashSet<T>类,主要被设计用来存储集合,做高性能集运算,例如 ...
- C#解惑:HashSet<T>类
原贴: https://blog.csdn.net/X_X_OO/article/details/52529548 https://www.cnblogs.com/refuge/p/9465466.h ...
- (转)HashSet<T>类
转载于:http://www.importnew.com/6931.html HashSet<T>类主要是设计用来做高性能集运算的,例如对两个集合求交集.并集.差集等.集合中包含一组不重复 ...
- Set接口HashSet实现类
java.util.Set接口 extends Collection接口 Set特点: 1.不允许有重复的元素 2.没有索引,没有带索引的方法,也不能使用普通的for遍历 java.util.Hash ...
- 微软在 .NET 3.5 新增了一个 HashSet 类,在 .NET 4 新增了一个 SortedSet 类,本文介绍他们的特性,并比较他们的异同。
微软在 .NET 3.5 新增了一个 HashSet 类,在 .NET 4 新增了一个 SortedSet 类,本文介绍他们的特性,并比较他们的异同. .NET Collection 函数库的 Has ...
- Nullable类型和HashSet<T>集合
今天接触到两个新的类型,查了一下才发现它们已经出现好久了,特作一下标记 Nullable结构 在System命名空间下,在 .NET Framework 2.0 版中是新增的:用它定义的值类型的对象与 ...
- 数据结构-List接口-LinkedList类-Set接口-HashSet类-Collection总结
一.数据结构:4种--<需补充> 1.堆栈结构: 特点:LIFO(后进先出);栈的入口/出口都在顶端位置;压栈就是存元素/弹栈就是取元素; 代表类:Stack; 其 ...
随机推荐
- pymysql-sqlalchemy-orm
sqlalchemy示例代码 多对多外键 场景:一个作者映射多个书籍,一个书籍有多个作者 作者表: id name email sex 1 Alex alex@.. M 2 Rail rail@.. ...
- JS根据日期获取判断星期几
/** * 根据日期字符串获取星期几 * @param dateString 日期字符串(如:2020-05-02) * @returns {String} */ function getWeek(d ...
- c++11之字符串格式化
1.关于 我知道的,C++20中引入了相当方便的字符串格式化,有兴趣的朋友,可以看下fmt库,截至目前,它实现了c++20中引入的字符串格式化绝大部分功能. 2.format 既然c++11中没有方便 ...
- 【LeetCode】509. Fibonacci Number 解题报告(C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 动态规划 日期 题目地址:https://leetc ...
- 警惕!PHP、Node、Ruby 和 Python 应用,漏洞还没结束!
12 月 10 日凌晨,Apache 开源项目 Log4j2 的远程代码执行漏洞细节被公开,作为当前全球使用最广泛的 java 日志框架之一.该漏洞影响着很多全球使用量前列的开源组件,如 Apache ...
- 应用程序开发 WebApp NativeApp 微信小程序
Web Native App 微信小程序 WebApp是指基于Web的系统和应用,其作用是向广大的最终用户发布一组复杂的内容和功能.webapp 框架是一种简单的与WSGI兼容的网络应用程序框 ...
- Chapter 5 Interaction
目录 5.1 Interaction requires a joint intervention 5.2 Identifying interaction 5.3 Counterfactual resp ...
- Layui 的内置jquery 版本
//layui-v2.4.5 的内置jquery 版本. console.log(layui.$.fn.jquery);//=> 1.12.3 可以使用内置jq的方法: 方法一: layui.u ...
- 什么是NaN?它的类型是什么?如何可靠的测试一个值是否等于NaN?
NaN属性表示"不是数字"的值.这个特殊值是由于一个操作数是非数字的(例如"abc"/4)或者因为操作的结果是非数字而无法执行的. 虽然看起来很简单,但是NaN ...
- windows环境jdk8下载安装与配置环境变量
1)jdk8官网下载地址 Java Downloads | Oracle 下载前需登录Oracle账号,没有的话可以用邮箱注册一个,登录之后即可进行下载. 2)jdk8安装 ①下载完成之后双击运行文件 ...