`
cakin24
  • 浏览: 1383729 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

Set最常见子类HashSet

    博客分类:
  • java
阅读更多

一 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 代码说明

上面代码中向books集合中分别添加了两个A对象,两个B对,两个C对象,其中C类重写equals()方法总是返回true,hashCode()方法总是返回2,这将导致HashSet把两个C对象当成同一个对象。注意:如果需要把某个类的对象保存到HashSet集合中,重写这个类的equals()方法和hashCode()方法时,应该尽量保证两个对象通过equals()方法比较返回true时,他们的hashCode()方法返回值也相等。

 四 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无法正确操作这些集合元素。

0
0
分享到:
评论

相关推荐

    List Set Map以及子类的比较 .docx

    HashSet、LinkedHashSet 和 TreeSet 是 Set 集合的三个常用的实现类。HashSet 使用 Hash 表结构,查询速度快,但不保证元素的顺序。LinkedHashSet 继承了 HashSet,添加了链表结构,保证了元素的顺序。TreeSet 使用...

    HashMap与HashTable和HashSet的区别

    在Java集合框架中,`HashMap`, `HashTable` 和 `HashSet` 是三个重要的数据结构,它们分别实现了`Map`接口和`Set`接口,提供了不同的功能来满足不同的编程需求。本文将重点分析这三种数据结构之间的区别,特别是针对...

    Java中Set的深入研究

    1. **不允许重复元素**:这是Set最显著的特点,它确保了集合中所有元素的唯一性。 2. **无序性**:大多数Set实现(如HashSet)不保证元素的插入顺序或自然排序。 3. **可选的线程安全性**:有些Set实现提供了线程...

    由HashSet谈重用

    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...

    JavaSE专题-Set集合.doc

    Set集合是JavaSE中的一种重要数据结构,主要包括HashSet、TreeSet和LinkedHashSet三个子类。下面我们将对Set集合的原理、特点、使用场景等进行详细的探索和分析。 HashSet HashSet是Set集合中的一种重要实现类,...

    java集合-LinkedHashSet的使用

    LinkedHashSet 是 Java 中的一个集合类,它是 HashSet 的子类,同时也实现了 Set 接口。与 HashSet 不同的是,LinkedHashSet 保留了元素插入的顺序,并且具有 HashSet 的快速查找特性。下面是关于 LinkedHashSet 的...

    常见的java面试题带答案

    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....

    Java 最常见 200+ 面试题全解析:面试必备

    - List、Set、Map接口:ArrayList、LinkedList、HashSet、TreeSet、HashMap、TreeMap等实现类的特性和使用场景。 - 泛型:理解泛型的作用,如何使用泛型类和泛型方法。 - 集合与数组的转换,以及集合操作(添加、...

    个人JavaSE学习笔记(观看圣思园的视频总结下来的)

    - Set接口及其子类如HashSet可用于存储不重复的元素。 - 在自定义对象的类中重写equals和hashCode方法是正确使用Set集合的关键。 - 迭代器是一种设计模式,用于遍历集合中的元素而不暴露其内部表示。 - Java集合框架...

    关于集合的小例子java

    HashSet<String> set = new HashSet(); set.add("Unique1"); set.add("Unique2"); set.add("Unique1"); // 不会添加,因元素已存在 System.out.println(set); // 输出:{Unique1, Unique2} ``` 这些小例子展示了...

    【List、Set、数据结构、Collections】.pdf

    LinkedHashSet是HashSet的子类,它在内部维护了一个链表来保持插入顺序,而TreeSet基于红黑树实现,可以保证元素的自然排序或根据构造器提供的Comparator进行排序。 Collections类是一个包含各种用于操作集合的静态...

    day03_List、Set 每日作业卷1

    LinkedHashSet是HashSet的子类,保留了元素的插入顺序。遍历LinkedHashSet时,元素会按照插入顺序进行,这与HashSet不同。 【Collections工具类使用】 Collections工具类提供了许多对集合操作的方法,如sort()用于...

    JAVA集合类[参考].pdf

    `Set`接口有两个常见的实现类:`HashSet`和`TreeSet`。`HashSet`基于散列(哈希)表,通过`hashCode()`方法快速定位元素,提供高效的添加、删除和查找操作。然而,它不保证元素的顺序,元素的顺序可能会随时间改变。...

    Java常见基础面试题.zip

    5. **集合面试题**:Java集合框架是处理对象组的重要工具,包括List(如ArrayList和LinkedList)、Set(如HashSet和TreeSet)和Map(如HashMap和TreeMap)等接口以及其实现类。面试中可能涉及的问题包括集合的遍历、...

    map,list,set,stack,queue,vector等区别和特点1

    HashSet是最常见的实现,它依赖于哈希表提供快速查找,但无特定顺序;LinkedHashSet保持插入顺序,而TreeSet根据元素自然排序或自定义比较器进行排序。 Map接口是键值对的集合,它不包含在Collection接口中,但与之...

    Java集合排序及java集合类详解(Collection、List、Map、Set

    `HashSet`是最常用的`Set`实现,基于`HashMap`,提供了快速的查找性能。`TreeSet`则提供排序功能。 #### 1.5.2 常用方法 `Set`接口继承自`Collection`,因此提供了相同的方法。 #### 1.5.3 实现原理 `HashSet`...

    Java学习笔记

    HashSet的一些常见操作包括add(E e)添加元素,retainAll(Collection<?> c)保留与给定集合的交集,和addAll(Collection<? extends E> c)合并两个集合得到并集。 3. **List接口与Set接口**: List接口是Collection的子...

    android学习 整理

    Set接口的子类如HashSet保证元素唯一性,TreeSet则可以进行排序。 2. IO流:Java的IO流用于读写数据,分为字节流和字符流,以及输入流和输出流。流的处理通常涉及文件操作、网络通信等场景。 3. 多线程:Android...

    Java集合框架常见面试题.pdf

    Set接口代表不包含重复元素的集合,常见的实现有HashSet、LinkedHashSet和TreeSet。HashSet是基于哈希表实现的,插入和查找速度快,但不保证元素的顺序;LinkedHashSet则在HashSet的基础上保持了元素的插入顺序;...

Global site tag (gtag.js) - Google Analytics