hashset java 键值对_Java集合 - HashSet的定义以及用法

HashSet的定义

HashSet类实现了Set接口,由一个实际上是HashMap实例的散列表​支持。不能保证该集合的迭代次序,这意味着该类不能保证元素随时间的不变顺序。这个类允许null元素。该类还为基本操作(如添加,删除,包含和大小)提供了恒定的时间性能,假定散列函数将元素正确地分散到桶中,我们将在文章中进一步讨论。
HashSet的一些重要特性是:

  • 实现Set Interface。
  • HashSet的基础数据结构是散列表。
  • 由于它实现了Set Interface,所以不允许重复值。
  • 您在HashSet中插入的对象不保证以相同顺序插入。对象基于其哈希码插入。
  • HashSet中允许使用NULL元素。
  • HashSet还实现了Searlizable和Cloneable接口。
04d5de06248c715d6c9b2b6609b5a18a.png

现在为了维持恒定的时间性能,迭代HashSet需要的时间与HashSet实例的大小(元素数量)加上支持HashMap实例的“容量”(桶的数量)的总和成正比。因此,如果迭代性能很重要,不要将初始容量设置得太高(或者负载因子太低)是非常重要的。

初始容量:初始容量意味着在创建散列表(HashSet内部使用散列表数据结构)时创建桶的数量。如果当前尺寸变满,桶的数量将自动增加。负载因数:负载因数是衡量HashSet在其容量自动增加之前能够获得的满量程。当哈希表中的条目数量超过负载因子和当前容量的乘积时,散列表就会被重新映射(即重建内部数据结构),以便散列表大约是存储桶数量的两倍。

                  表格中存储的元素数量   加载因子= -----------------------------------------                        散列表的大小 

示例:如果内部容量为16并且加载因子为0.75,那么当表中有12个元素时,桶的数量会自动增加。

对性能的影响:
负载因子和初始容量是影响HashSet操作性能的两个主要因素。0.75的负载因子在时间和空间复杂度方面提供了非常有效的性能。如果我们将负载因子值增加得超过这个值,那么内存开销将会减少(因为它会减少内部重建操作),但是它会影响哈希表中的添加和搜索操作。为了减少重新哈希操作,我们应该明智地选择初始容量。如果初始容量大于最大入口数量除以负载因子,则不会发生重新刷新操作。

注:HashSet中的实现不同步,因为如果多个线程同时访问散列集,并且至少有一个线程修改了该集,它必须在外部同步。这通常是通过在自然封装集合的某个对象上进行同步来完成的。如果不存在这样的对象,则应该使用Collections.synchronizedSet方法来“包装”该集合。这最好在创建时完成,以防止意外的不同步访问集合,如下所示:

Set s = Collections.synchronizedSet(new HashSet(...));

HashSet中的构造函数:

  1. HashSet h = new HashSet();
    默认初始容量为16,默认加载因子为0.75。
  2. HashSet h = new HashSet(int initialCapacity);
    默认的0.75的loadFactor
  3. HashSet h = new HashSet(int initialCapacity,float loadFactor);
  4. HashSet h = new HashSet(Collection C);

下面的程序说明了HashSet的几个基本操作:

// Java program to demonstrate working of HashSet

import java.util.*;

class Test

{

public static void main(String[]args)

{

HashSet h = new HashSet();

// Adding elements into HashSet usind add()

h.add("India");

h.add("Australia");

h.add("South Africa");

h.add("India");// adding duplicate elements

// Displaying the HashSet

System.out.println(h);

System.out.println("List contains India or not:" +

h.contains("India"));

// Removing items from HashSet using remove()

h.remove("Australia");

System.out.println("List after removing Australia:"+h);

// Iterating over hash set items

System.out.println("Iterating over list:");

Iterator i = h.iterator();

while (i.hasNext())

System.out.println(i.next());

}

}

输出:

[South Africa, Australia, India]List contains India or not:trueList after removing Australia:[South Africa, India]Iterating over list:South AfricaIndia

HashSet的内部工作
由Map内部备份的所有Set接口类。HashSet使用HashMap在内部存储它的对象。您一定想知道,要在HashMap中输入值,我们需要一个键值对,但在HashSet中,我们只传递一个值。

存储在HashMap中
实际上,我们在HashSet中插入的值作为映射对象的关键字,并且其值java使用常量变量。所以在键值对中,所有键都具有相同的值。

在java文档中实现HashSet

private transient HashMap map;//构造函数 -  1//所有的构造函数都在内部创建HashMap对象。public HashSet(){    //创建内部支持HashMap对象    map = new HashMap();}//构造函数 -  2public HashSet(int initialCapacity){    //创建内部支持HashMap对象    map = new HashMap(initialCapacity);}//与map中的对象关联的虚拟值private static final Object PRESENT = new Object();

如果我们看一下HashSet类的add()方法:

public boolean add(E e){   return map.put(e,PRESENT)== null;}

我们可以注意到,HashSet类的add()方法通过传递指定的元素作为键和常量“PRESENT”作为其值,来内部调用支持HashMap对象的put()方法。

remove()方法也以相同的方式工作。它内部调用Map接口的remove方法。

public boolean remove(Object o){  return map.remove(o)== PRESENT;}

HashSet操作的时间复杂度:HashSet的基础数据结构是散列表。因此,对于添加,移除和查找(包含方法)操作,HashSet需要O(1)次的时间复杂度(平均或通常情况下)的时间复杂度。

HashSet中的方法:

  1. boolean add(E e):用于添加指定元素(如果不存在),如果存在则返回false。
  2. void clear():用于删除set中的所有元素。
  3. boolean contains(Object o): 如果元素存在于set中,则返回true。
  4. boolean remove(Object o):用于删除元素,如果它存在于set中。
  5. Iterator iterator(): 用于返回集合中元素的迭代器。
  6. boolean isEmpty():用于检查集合是否为空。返回true表示空,false表示非空条件。
  7. int size():用于返回集合的大小。
  8. Object clone():用于创建集合的浅表副本。

--------------------------------------------------------

转载自:https://www.breakyizhan.com/java/4658.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Java 集合是一个存储对象的数据结构,可以在程序中方便地进行数据的存储、检索和操作。它是 Java 标准库的一部分,提供了许多内置的容器类,如 List、Set、Map 等。这些容器类都实现了 Collection 接口,定义了一些基本的数据存储和操作方法,如 add、remove、size 等。 通过使用 Java 集合,可以简化代码,提高程序的可读性和可维护性,也可以提高程序的效率。 ### 回答2: Java集合是用于存储和处理一组相关数据对象的容器。它是Java编程语言中非常重要的一部分,提供了一系列接口和类来实现不同类型和功能的集合Java集合框架提供了多种集合实现,以满足不同的应用需求。 Java集合可以根据其结构分为两大类:一是单列集合,如List、Set和Queue;二是双列集合,如Map。 List是有序的集合,可以包含重复元素。它有多个实现类,其中比较常用的是ArrayList和LinkedList。ArrayList底层采用动态数组实现,支持随机访问,适用于频繁访问和修改的场景。而LinkedList底层采用双向链表实现,适用于频繁插入和删除的场景。 Set是无序且不可包含重复元素的集合。它有多个实现类,例如HashSet和TreeSet。HashSet基于哈希表实现,具有较快的元素查找和插入速度,而TreeSet基于红黑树实现,可以按照元素的自然顺序进行排序。 Queue是一种先进先出(FIFO)的集合,它用于存储和操作待处理元素。常用的实现类有LinkedList和PriorityQueue。 Map是一种键值对集合,每个键对应一个唯一的值。常见的实现类有HashMap和TreeMap。HashMap基于哈希表实现,可以快速进行键值对的查找和插入操作,而TreeMap则基于红黑树实现,可以按照键的自然顺序对键值对进行排序。 除了以上常用的集合类,Java集合框架还提供了一些辅助类和接口,如Collections和Iterator,用于提供集合的各种操作和迭代访问。 Java集合提供了一种便捷的方式来管理和操作数据,极大地简化了编程工作。开发者可以根据需求选择合适的集合类,提高代码的可读性、可维护性和性能。 ### 回答3: Java集合Java语言中的一种数据结构,用于存储和操作一组数据。Java集合提供了一系列的接口和类,用于实现不同类型的集合Java集合框架主要由以下几个核心接口和类组成: 1. Collection接口:是所有集合类的父接口,定义集合类的基本操作,如添加、删除、遍历等。常用的实现类有List(有序可重复集合)、Set(无序不可重复集合)和Queue(队列)。 2. Map接口:用于存储键值对的数据结构,每个键唯一对应一个值。Map接口的常用实现类有HashMap、TreeMap和LinkedHashMap。 3. ArrayList类:实现了List接口,基于数组实现的动态数组。它可以根据需要自动扩容,支持动态增删元素。 4. LinkedList类:实现了List和Queue接口,基于双向链表实现的。它可以高效地完成插入、删除等操作,适用于频繁插入和删除操作的场景。 5. HashSet类:实现了Set接口,基于哈希表实现的无序不可重复集合。它使用了哈希函数来计算元素的存储位置,查找元素的速度非常快。 6. HashMap类:实现了Map接口,基于哈希表实现的键值对集合。它可以根据键快速地查找对应的值,具有很高的查找效率。 Java集合提供了丰富的功能和操作方法,可以方便地进行元素的增删改查、遍历、排序以及集合间的操作,如并集、交集和差集等。它们的使用可以大大简化程序的编和维护工作,提高代码的可读性和可维护性。 同时,Java集合还具有泛型的特性,使得集合类可以更加灵活地存储不同类型的数据。通过明确指定集合存储的元素类型,可以在编译时提供更好的类型检查,减少运行时错误的发生。 总之,Java集合Java程序开发中非常重要和常用的一个部分,它提供了丰富的功能和灵活的数据存储方式,可以满足各种需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值