一 HashSet概述
HashSet是Set接口的典型实现,大多时候使用Set集合时就是使用这个实现类。HashSet按Hash算法来存储集合中的元素,因此具有很好的存取和查找性能。
当向HashSet集合中存入一个元素时,HashSet会调用该对象的hashCode()方法来得到该对象的hashCode值,然后根据该HashCode值来决定该对象在HashSet中存储位置。如果有两个元素通过equals方法比较返回true,但它们的hashCode()方法返回值不相等,HashSet将会把它们存储在不同位置,也就可以添加成功。也就是说,HashSet集合判断两个元素相等的标准是通过equals()方法比较相等、并且两个对象的hashCode()方法的返回值也相等。
二 HashSet具有以下特点
-
不能保证元素的排列顺序,顺序可能与元素的添加顺序不同,元素的顺序可能变化。
-
HashSet不是同步的,如果多个线程同时访问一个HashSet,如果有2条或者2条以上线程同时修改了HashSet集合时,必须通过代码来保证其同步。
-
集合元素值可以是null。
三 HashSet无重复性应用
1 代码示例
import java.util.*; // 类A的equals方法总是返回true,但没有重写其hashCode()方法 class A { public boolean equals(Object obj) { return true; } } // 类B的hashCode()方法总是返回1,但没有重写其equals()方法 class B { public int hashCode() { return 1; } } // 类C的hashCode()方法总是返回2,且重写其equals()方法总是返回true class C { public int hashCode() { return 2; } public boolean equals(Object obj) { return true; } } public class HashSetTest { public static void main(String[] args) { HashSet books = new HashSet(); // 分别向books集合中添加两个A对象,两个B对象,两个C对象 books.add(new A()); books.add(new A()); books.add(new B()); books.add(new B()); books.add(new C()); books.add(new C()); System.out.println(books); } }
2 运行结果
[B@1, B@1, C@2, A@1db9742, A@106d69c]
3 代码说明
四 HashSet混乱示例
1 代码示例
import java.util.*; class R { int count; public R(int count) { this.count = count; } public String toString() { return "R[count:" + count + "]"; } public boolean equals(Object obj) { if(this == obj) return true; if (obj != null && obj.getClass() == R.class) { R r = (R)obj; return this.count == r.count; } return false; } public int hashCode() { return this.count; } } public class HashSetTest2 { public static void main(String[] args) { HashSet hs = new HashSet(); hs.add(new R(5)); hs.add(new R(-3)); hs.add(new R(9)); hs.add(new R(-2)); // 打印HashSet集合,集合元素没有重复 System.out.println(hs); // 取出第一个元素 Iterator it = hs.iterator(); R first = (R)it.next(); // 为第一个元素的count实例变量赋值 first.count = -3; // ① // 再次输出HashSet集合,集合元素有重复元素 System.out.println(hs); // 删除count为-3的R对象 hs.remove(new R(-3)); // ② // 可以看到被删除了一个R元素 System.out.println(hs); System.out.println("hs是否包含count为-3的R对象?" + hs.contains(new R(-3))); // 输出false System.out.println("hs是否包含count为-2的R对象?" + hs.contains(new R(-2))); // 输出false } }
2 运行结果
[R[count:-2], R[count:-3], R[count:5], R[count:9]]
[R[count:-3], R[count:-3], R[count:5], R[count:9]]
[R[count:-3], R[count:5], R[count:9]]
hs是否包含count为-3的R对象?false
hs是否包含count为-2的R对象?false
3 代码说明
当程序把可变成员变量加入到HashSet中之后,尽量不要去修改该集合元素中参与计算hashCode()、equals()变量,否则将会导致HashSet无法正确操作这些集合元素。
相关推荐
LinkedHashSet 是 Java 中的一个集合类,它是 HashSet 的子类,同时也实现了 Set 接口。与 HashSet 不同的是,LinkedHashSet 保留了元素插入的顺序,并且具有 HashSet 的快速查找特性。下面是关于 LinkedHashSet 的...
List接口、ArrayList类、Vector类、栈操作类Stack、链表操作类LinkList、队列操作接口Queue、Set接口、HashSet类、TreeSet类、SortedSet接口 双值操作接口Map(key->value)及其子接口、子类: SortedMap接口、HashMap...
jdk 的集合框架的主体结构: Set 成员不能重复 HashSet 外部无序地遍历成员。 成员可为任意Object子类的对象,但如果覆盖了equals方法,同时注意修改hashCode方法。
Set 接口 AbstractSet 抽象类SortedSet 接口HashSet LinkedHashSet TreeSet List 接口 AbstractList 和 AbstractSequentialList Vector Stack ArrayList LinkedList Queue接口Deque 接口 AbstractQueue 抽象类...
个人学习总结,仅供参考。详细介绍集合中常用的方法并附带了相关代码,对Collection的子类:List(ArrayList、LinkedList)及Set(HashSet、TreeSet)进行了详细的介绍。
开发者核心持久性持久性库提供Entity Framework Core和存储库和工作单元模式的内存中实现(通过HashSet)。 针对.NET 5.0快速开始通过实现IEntity或IEntity接口或通过从EntityBase基类继承来定义您的实体。 public ...
3.1.2 HashMap和HashSet 3.1.3 TreeMap和TreeSet 3.2 Map和List 3.2.1 Map的values()方法 3.2.2 Map和List的关系 3.3 ArrayList和LinkedList 3.3.1 Vector和ArrayList的区别 3.3.2 ArrayList和LinkedList...
类:ArrayList、Math、HashMap、String、StringBuffer、HashSet 、Thread 、Integer。 接口:Connection、Map、List、Set、Comparable(集合比较)、Serializable(序列化)。 包:java.util、java.lang、java.io、java....
2. Set接口 2.1 HashSet集合 2.2 HashSet集合存储结构(哈希表) 2.3 HashSet存储自定义类型元素 2.4 LinkedHashSet类 2.5 可变参数 3. Collections 3.1 Comparator比较器 3.2 Comparable和Comparator两个接口的区别...
java8 集合源码分析 java基础复习 [TOC] 一、集合 1.Iterator 2.Collection 2.1 List--->有序、有索引、元素可重复 ...有序,是HashSet的子类 2.TreeSet: 底层是二叉树,可对元素进行排序,默认是自然顺序
1,编写程序,判断给定的某个年份是否是闰年。 闰年的判断规则如下: (1)若某个年份能被4整除但不能被100整除,则是闰年。 (2)若某个年份能被400整除,则也是闰年。 import java.util.Scanner;...
学生提问:既然内部类是外部类的成员,是否可以为外部类定义子类,在子类中再定义一个内部类来重写其父类中的内部类? 211 6.7.4 局部内部类 211 6.7.5 匿名内部类 212 6.7.6 闭包(Closure)和回调 215 6.8 ...
10.2 子类对象?父类对象? 251 10.2.1 父随子行 251 10.2.2 当构造方法遇到继承 254 10.2.3 记得给类一个无参数的构造方法 255 10.2.4 调用父类中的构造方法 256 10.2.5 对象也会“变脸” 258 10.2.6 遵守...
10.2 子类对象?父类对象? 251 10.2.1 父随子行 251 10.2.2 当构造方法遇到继承 254 10.2.3 记得给类一个无参数的构造方法 255 10.2.4 调用父类中的构造方法 256 10.2.5 对象也会“变脸” 258 10.2.6 遵守...
11.2.4哈希集合(HashSet)使用示例343 11.2.5哈希映射类(HashMap)使用示例347 11.2.6有序树(TreeSet)使用示例349 11.2.7有序树映射类(TreeMap)使用示例353 11.2.8枚举(Enum)使用示例355 11.2.9枚举集...