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; 其 ...
随机推荐
- Spring整合redis实现key过期事件监听
打开redis服务的配置文件 添加notify-keyspace-events Ex 如果是注释了,就取消注释 这个是在以下基础上进行添加的 Spring整合redis:https://www. ...
- OnZoom 基于Apache Hudi的流批一体架构实践
1. 背景 OnZoom是Zoom新产品,是基于Zoom Meeting的一个独一无二的在线活动平台和市场.作为Zoom统一通信平台的延伸,OnZoom是一个综合性解决方案,为付费的Zoom用户提供创 ...
- 使用.NET 6开发TodoList应用(8)——实现全局异常处理
系列导航 使用.NET 6开发TodoList应用文章索引 需求 因为在项目中,会有各种各样的领域异常或系统异常被抛出来,那么在Controller里就需要进行完整的try-catch捕获,并根据是否 ...
- 【LeetCode】1471. 数组中的 k 个最强值 The k Strongest Values in an Array (Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 自定义排序 日期 题目地址:https://leetc ...
- Network (poj1144)
A Telephone Line Company (TLC) is establishing a new telephone cable network. They are connecting se ...
- 1164 - Horrible Queries
1164 - Horrible Queries PDF (English) Statistics Forum Time Limit: 2 second(s) Memory Limit: 64 M ...
- Frp内网穿透搭建,家庭主机对外提供接口,支持ssh访问
Frp内网穿透搭建,家庭主机对外提供接口,支持ssh访问 1.使用场景: 需求1.家中服务器 ubuntu 主机,跑接口服务,需要对外暴漏, 需求2.同时需要在外网ssh远程 关键词: frp内网 ...
- 第四十六个知识点 在Sigma协议中,正确性,公正性和零知识性意味着什么
第四十六个知识点 在Sigma协议中,正确性,公正性和零知识性意味着什么 Sigma协议 Sigma协议是Alice想要向Bob证明一些东西的协议(Alice知道一些秘密).他们有下面的一般范式:Al ...
- 【优雅代码】03-optional杜绝空指针异常
[优雅代码]03-optional杜绝空指针异常 欢迎关注b站账号/公众号[六边形战士夏宁],一个要把各项指标拉满的男人.该文章已在github目录收录. 屏幕前的大帅比和大漂亮如果有帮助到你的话请顺 ...
- Java Web程序设计笔记 • 【第6章 Servlet技术进阶】
全部章节 >>>> 本章目录 6.1 应用 Servlet API(一) 6.1.1 Servlet 类的层次结构 6.1.2 使用 Servlet API 的原则 6.1 ...