一 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无法正确操作这些集合元素。
相关推荐
HashSet、LinkedHashSet 和 TreeSet 是 Set 集合的三个常用的实现类。HashSet 使用 Hash 表结构,查询速度快,但不保证元素的顺序。LinkedHashSet 继承了 HashSet,添加了链表结构,保证了元素的顺序。TreeSet 使用...
在Java集合框架中,`HashMap`, `HashTable` 和 `HashSet` 是三个重要的数据结构,它们分别实现了`Map`接口和`Set`接口,提供了不同的功能来满足不同的编程需求。本文将重点分析这三种数据结构之间的区别,特别是针对...
1. **不允许重复元素**:这是Set最显著的特点,它确保了集合中所有元素的唯一性。 2. **无序性**:大多数Set实现(如HashSet)不保证元素的插入顺序或自然排序。 3. **可选的线程安全性**:有些Set实现提供了线程...
public class HashSet<E> extends AbstractSet<E> implements Set, Cloneable, java.io.Serializable { private transient HashMap, Object> map; private static final Object PRESENT = new Object(); public...
Set集合是JavaSE中的一种重要数据结构,主要包括HashSet、TreeSet和LinkedHashSet三个子类。下面我们将对Set集合的原理、特点、使用场景等进行详细的探索和分析。 HashSet HashSet是Set集合中的一种重要实现类,...
LinkedHashSet 是 Java 中的一个集合类,它是 HashSet 的子类,同时也实现了 Set 接口。与 HashSet 不同的是,LinkedHashSet 保留了元素插入的顺序,并且具有 HashSet 的快速查找特性。下面是关于 LinkedHashSet 的...
Set<String> set1 = new HashSet(Arrays.asList(s1.split("\\s+"))); Set<String> set2 = new HashSet(Arrays.asList(s2.split("\\s+"))); return (double) set1.size() * set2.size() / (set1.size() + set2....
- List、Set、Map接口:ArrayList、LinkedList、HashSet、TreeSet、HashMap、TreeMap等实现类的特性和使用场景。 - 泛型:理解泛型的作用,如何使用泛型类和泛型方法。 - 集合与数组的转换,以及集合操作(添加、...
- Set接口及其子类如HashSet可用于存储不重复的元素。 - 在自定义对象的类中重写equals和hashCode方法是正确使用Set集合的关键。 - 迭代器是一种设计模式,用于遍历集合中的元素而不暴露其内部表示。 - Java集合框架...
HashSet<String> set = new HashSet(); set.add("Unique1"); set.add("Unique2"); set.add("Unique1"); // 不会添加,因元素已存在 System.out.println(set); // 输出:{Unique1, Unique2} ``` 这些小例子展示了...
LinkedHashSet是HashSet的子类,它在内部维护了一个链表来保持插入顺序,而TreeSet基于红黑树实现,可以保证元素的自然排序或根据构造器提供的Comparator进行排序。 Collections类是一个包含各种用于操作集合的静态...
LinkedHashSet是HashSet的子类,保留了元素的插入顺序。遍历LinkedHashSet时,元素会按照插入顺序进行,这与HashSet不同。 【Collections工具类使用】 Collections工具类提供了许多对集合操作的方法,如sort()用于...
`Set`接口有两个常见的实现类:`HashSet`和`TreeSet`。`HashSet`基于散列(哈希)表,通过`hashCode()`方法快速定位元素,提供高效的添加、删除和查找操作。然而,它不保证元素的顺序,元素的顺序可能会随时间改变。...
5. **集合面试题**:Java集合框架是处理对象组的重要工具,包括List(如ArrayList和LinkedList)、Set(如HashSet和TreeSet)和Map(如HashMap和TreeMap)等接口以及其实现类。面试中可能涉及的问题包括集合的遍历、...
HashSet是最常见的实现,它依赖于哈希表提供快速查找,但无特定顺序;LinkedHashSet保持插入顺序,而TreeSet根据元素自然排序或自定义比较器进行排序。 Map接口是键值对的集合,它不包含在Collection接口中,但与之...
`HashSet`是最常用的`Set`实现,基于`HashMap`,提供了快速的查找性能。`TreeSet`则提供排序功能。 #### 1.5.2 常用方法 `Set`接口继承自`Collection`,因此提供了相同的方法。 #### 1.5.3 实现原理 `HashSet`...
HashSet的一些常见操作包括add(E e)添加元素,retainAll(Collection<?> c)保留与给定集合的交集,和addAll(Collection<? extends E> c)合并两个集合得到并集。 3. **List接口与Set接口**: List接口是Collection的子...
Set接口的子类如HashSet保证元素唯一性,TreeSet则可以进行排序。 2. IO流:Java的IO流用于读写数据,分为字节流和字符流,以及输入流和输出流。流的处理通常涉及文件操作、网络通信等场景。 3. 多线程:Android...
Set接口代表不包含重复元素的集合,常见的实现有HashSet、LinkedHashSet和TreeSet。HashSet是基于哈希表实现的,插入和查找速度快,但不保证元素的顺序;LinkedHashSet则在HashSet的基础上保持了元素的插入顺序;...