`
cakin24
  • 浏览: 1335736 次
  • 性别: 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
分享到:
评论

相关推荐

    java集合-LinkedHashSet的使用

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

    Java期末复习-类集框架

    List接口、ArrayList类、Vector类、栈操作类Stack、链表操作类LinkList、队列操作接口Queue、Set接口、HashSet类、TreeSet类、SortedSet接口 双值操作接口Map(key->value)及其子接口、子类: SortedMap接口、HashMap...

    jdk 的集合框架的主体结构

    jdk 的集合框架的主体结构: Set 成员不能重复 HashSet 外部无序地遍历成员。 成员可为任意Object子类的对象,但如果覆盖了equals方法,同时注意修改hashCode方法。

    Java 基础核心总结 +经典算法大全.rar

    Set 接口 AbstractSet 抽象类SortedSet 接口HashSet LinkedHashSet TreeSet List 接口 AbstractList 和 AbstractSequentialList Vector Stack ArrayList LinkedList Queue接口Deque 接口 AbstractQueue 抽象类...

    Collection.xmind

    个人学习总结,仅供参考。详细介绍集合中常用的方法并附带了相关代码,对Collection的子类:List(ArrayList、LinkedList)及Set(HashSet、TreeSet)进行了详细的介绍。

    Developist.Core.Persistence:实体框架核心和存储库和工作单元模式的内存中实现

    开发者核心持久性持久性库提供Entity Framework Core和存储库和工作单元模式的内存中实现(通过HashSet)。 针对.NET 5.0快速开始通过实现IEntity或IEntity接口或通过从EntityBase基类继承来定义您的实体。 public ...

    突破程序员基本功的16课.part2

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

    java面试考题

    类:ArrayList、Math、HashMap、String、StringBuffer、HashSet 、Thread 、Integer。 接口:Connection、Map、List、Set、Comparable(集合比较)、Serializable(序列化)。 包:java.util、java.lang、java.io、java....

    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集合源码分析-CollectionDemo:自己复习集合框架时候的例子

    java8 集合源码分析 java基础复习 [TOC] 一、集合 1.Iterator 2.Collection 2.1 List--->有序、有索引、元素可重复 ...有序,是HashSet的子类 2.TreeSet: 底层是二叉树,可对元素进行排序,默认是自然顺序

    达内 coreJava 习题答案

    1,编写程序,判断给定的某个年份是否是闰年。 闰年的判断规则如下: (1)若某个年份能被4整除但不能被100整除,则是闰年。 (2)若某个年份能被400整除,则也是闰年。 import java.util.Scanner;...

    疯狂JAVA讲义

    学生提问:既然内部类是外部类的成员,是否可以为外部类定义子类,在子类中再定义一个内部类来重写其父类中的内部类? 211 6.7.4 局部内部类 211 6.7.5 匿名内部类 212 6.7.6 闭包(Closure)和回调 215 6.8 ...

    JAVA入门1.2.3:一个老鸟的JAVA学习心得 PART1(共3个)

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

    Java入门1·2·3:一个老鸟的Java学习心得.PART3(共3个)

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

    Java开发技术大全 电子版

    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枚举集...

Global site tag (gtag.js) - Google Analytics