博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java中hashset_Java HashSet – Java中的HashSet
阅读量:2534 次
发布时间:2019-05-11

本文共 17381 字,大约阅读时间需要 57 分钟。

java中hashset

Java HashSet is the most popular implementation of Set interface. java.util.HashSet is backed by a HashMap. HashSet extends AbstractSet class and implements Set, Cloneable and Serializable interfaces.

Java HashSet是Set接口的最流行实现。 HashMap支持java.util.HashSet。 HashSet扩展了AbstractSet类并实现Set,Cloneable和Serializable接口。

Java HashSet (Java HashSet)

Some of the important points about HashSet in java are;

Java中有关HashSet的一些重要要点是:

  1. HashSet doesn’t allow duplicate entries.

    HashSet不允许重复的条目。
  2. HashSet allows null as a value.

    HashSet允许将null作为值。
  3. HashSet doesn’t guarantee the insertion order of elements.

    HashSet不保证元素的插入顺序。
  4. HashSet is not thread-safe. You can get thread-safe HashSet using Collections.synchronizedSet method at the cost of performance. You can also use CopyOnWriteArraySet concurrency class for thread safety.

    HashSet不是线程安全的。 您可以使用Collections.synchronizedSet方法获取线程安全的HashSet,但会降低性能。 您也可以将CopyOnWriteArraySet并发类用于线程安全。
  5. HashSet iterator methods are fail-fast. So any structural modification to the set after creation of iterator will throw ConcurrentModificationException.

    HashSet迭代器方法快速失败。 因此,在创建迭代器之后对该集合进行的任何结构修改都将引发ConcurrentModificationException。
  6. HashSet supports Generics, this is the recommended approach to avoid ClassCastException at runtime.

    HashSet支持泛型,这是在运行时避免ClassCastException的推荐方法。
  7. HashSet uses for storing elements, so the objects should provide good implementation of hashCode() and equals() method to avoid unwanted results.

    HashSet使用来存储元素,因此对象应提供hashCode()和equals()方法的良好实现,以避免产生不必要的结果。

Java HashSet构造函数 (Java HashSet Constructors)

Java HashSet provides four constructors.

Java HashSet提供了四个构造函数。

  1. public HashSet(): Creates a new empty HashSet, the backing HashMap is initialized with default initial capacity as 16 and load factor 0.75.

    public HashSet() :创建一个新的空HashSet,使用默认的初始容量16和负载因子0.75初始化后备HashMap。
  2. public HashSet(int initialCapacity): Creates a empty HashSet with backing HashMap initialized with specified capacity and load factor 0.75.

    public HashSet(int initialCapacity) :创建一个空HashSet,并使用指定的容量和负载系数0.75初始化后备HashMap。
  3. public HashSet(int initialCapacity, float loadFactor): Creates a empty HashSet with backing HashMap initialized with specified capacity and specified load factor.

    public HashSet(int initialCapacity,float loadFactor) :创建一个空HashSet,并使用指定的容量和指定的加载因子初始化后备HashMap。
  4. public HashSet(Collection<? extends E> c): Creates a new Set containing the elements in the specified collection. The backing HashMap is created with default load factor (0.75) and an initial capacity sufficient enough to contain all the elements in the specified collection.

    public HashSet(Collection <?extends E> c) :创建一个包含指定集合中元素的新Set。 使用默认的加载因子(0.75)和足以容纳指定集合中所有元素的初始容量创建后备HashMap。

Below code snippet is showing all these HashSet constructors example usage.

下面的代码片段显示了所有这些HashSet构造函数示例用法。

Set
set = new HashSet<>();//initial capacity should be power of 2set = new HashSet<>(32); //setting backing HashMap initial capacity and load factorset = new HashSet<>(32, 0.80f);//creating HashSet from another CollectionSet
set1 = new HashSet<>(set);Set
set2 = new HashSet<>(new ArrayList<>());

Java HashSet方法 (Java HashSet Methods)

Some of the useful HashSet methods are;

一些有用的HashSet方法是:

  1. public boolean add(E e): Adds the given element to the Set if not already present. This method internally uses equals() method to check for duplicates, so make sure your object defines equals() method properly.

    public boolean add(E e) :如果给定元素不存在,则将其添加到Set中。 此方法在内部使用equals()方法检查重复项,因此请确保您的对象正确定义了equals()方法。
  2. public void clear(): Removes all the elements from the Set.

    public void clear() :从集合中删除所有元素。
  3. public Object clone(): Returns a shallow copy of the Set instance.

    public Object clone() :返回Set实例的浅表副本。
  4. public boolean contains(Object o): Returns true if the Set contains the given element, othrweise false.

    public boolean contains(Object o) :如果Set包含给定元素,则返回true,否则返回false。
  5. public boolean isEmpty(): Returns true if Set contains no elements, otherwise false.

    public boolean isEmpty() :如果Set不包含任何元素,则返回true,否则返回false。
  6. public Iterator<E> iterator(): Returns an iterator over the elements in this set. The elements are returned in no particular order.

    public Iterator <E> iterator() :返回对此集合中的元素进行迭代的迭代器。 元素以不特定的顺序返回。
  7. public boolean remove(Object o): Removes the given element from this set if it is present and return true. If the element is not present in the set, just returns false.

    public boolean remove(Object o) :从该集合中删除给定的元素(如果存在)并返回true。 如果该元素不存在,则返回false。
  8. public int size(): Returns the number of elements in the set.

    public int size() :返回集合中元素的数量。
  9. public Spliterator<E> spliterator(): Creates a late-binding and fail-fast Spliterator over the elements in this set. This is introduced in Java 8, however I have not used it till now.

    public Spliterator <E> splitter() :在此集合中的元素上创建后绑定和故障快速的Spliterator。 这是Java 8中引入的,但是到目前为止我还没有使用过。
  10. public boolean removeAll(Collection<?> c): HashSet inherits this method from AbstractSet. This method will remove all the elements in the set that are part of the specified collection.

    public boolean removeAll(Collection <?> c) :HashSet从AbstractSet继承此方法。 此方法将删除集合中属于指定集合的​​所有元素。

Java HashSet示例 (Java HashSet Example)

Java HashSet example program showing common usage of HashSet in java.

Java HashSet示例程序,显示了Java中HashSet的常见用法。

package com.journaldev.examples;import java.util.ArrayList;import java.util.HashSet;import java.util.Iterator;import java.util.List;import java.util.Set;public class HashSetExample {	public static void main(String[] args) {		Set
fruits = new HashSet<>(); //add example fruits.add("Apple"); fruits.add("Banana"); //isEmpty example System.out.println("fruits set is empty = "+fruits.isEmpty()); //contains example System.out.println("fruits contains Apple = "+fruits.contains("Apple")); System.out.println("fruits contains Mango = "+fruits.contains("Mango")); //remove example System.out.println("Apple removed from fruits set = "+fruits.remove("Apple")); System.out.println("Mango removed from fruits set = "+fruits.remove("Mango")); //size example System.out.println("fruits set size = "+fruits.size()); //addAll example List
list = new ArrayList<>(); list.add("Apple"); list.add("Apple"); list.add("Banana"); list.add("Mango"); System.out.println("fruits set before addAll = "+fruits); System.out.println("list = "+list); fruits.addAll(list); System.out.println("fruits set after addAll = "+fruits); //iterator example Iterator
iterator = fruits.iterator(); while(iterator.hasNext()){ System.out.println("Consuming fruit "+iterator.next()); } //removeAll example fruits.add("Orange"); System.out.println("fruits set before removeAll = "+fruits); System.out.println("list = "+list); fruits.removeAll(list); System.out.println("fruits set after removeAll = "+fruits); //clear example fruits.clear(); System.out.println("fruits set is empty = "+fruits.isEmpty()); }}

Output of above HashSet example program is given below, I am not explaining them since they are self understood.

上面的HashSet示例程序的输出如下所示,因为它们是我自己理解的,所以我不解释它们。

fruits set is empty = falsefruits contains Apple = truefruits contains Mango = falseApple removed from fruits set = trueMango removed from fruits set = falsefruits set size = 1fruits set before addAll = [Banana]list = [Apple, Apple, Banana, Mango]fruits set after addAll = [Apple, Mango, Banana]Consuming fruit AppleConsuming fruit MangoConsuming fruit Bananafruits set before removeAll = [Apple, Mango, Orange, Banana]list = [Apple, Apple, Banana, Mango]fruits set after removeAll = [Orange]fruits set is empty = true

Java HashSet ConcurrentModificationException示例 (Java HashSet ConcurrentModificationException Example)

Java HashSet iterator is fail-fast, so it’s methods will throw java.util.ConcurrentModificationException if Set is structurally modified. Below is a simple example demonstrating this.

Java HashSet迭代器是快速失败的,因此,如果对Set进行结构上的修改,它的方法将抛出java.util.ConcurrentModificationException 。 下面是一个简单的示例来说明这一点。

package com.journaldev.examples;import java.util.HashSet;import java.util.Iterator;import java.util.Set;public class HashSetConcurrentModificationExceptionExample {	public static void main(String[] args) {		Set
fruits = new HashSet<>(); //add example fruits.add("Apple"); fruits.add("Banana"); fruits.add("Orange"); fruits.add("Mango"); Iterator
iterator = fruits.iterator(); while(iterator.hasNext()){ String fruit = iterator.next(); System.out.println("Processing "+fruit); //wrong way of removing from Set, can throw java.util.ConcurrentModificationException if("Orange".equals(fruit)) fruits.remove("Orange"); } }}

I am getting below output and exception when above program is executed.

执行上面的程序时,我得到下面的输出和异常。

Processing AppleProcessing MangoProcessing OrangeException in thread "main" java.util.ConcurrentModificationException	at java.util.HashMap$HashIterator.nextNode(HashMap.java:1429)	at java.util.HashMap$KeyIterator.next(HashMap.java:1453)	at com.journaldev.examples.HashSetConcurrentModificationExceptionExample.main(HashSetConcurrentModificationExceptionExample.java:21)

Note that HashSet elements are not guaranteed to be ordered and is being thrown by iterator.next() call. So if the “Orange” is the last one in the iterator, you will not get the exception because iterator.hasNext() will return false and iterator.next() will not get called.

请注意,不能保证HashSet元素是有序的,并且iterator.next()调用会引发 。 因此,如果“橙色”是迭代器中的最后一个,则不会收到异常,因为iterator.hasNext()将返回false,并且iterator.next()将不会被调用。

We should always use Iterator methods for structural modification, as shown in below example code.

我们应该始终使用Iterator方法进行结构修改,如下面的示例代码所示。

package com.journaldev.examples;import java.util.HashSet;import java.util.Iterator;import java.util.Set;public class HashSetConcurrentModificationExceptionExample {	public static void main(String[] args) {		Set
fruits = new HashSet<>(); fruits.add("Apple"); fruits.add("Banana"); fruits.add("Orange"); fruits.add("Mango"); Iterator
iterator = fruits.iterator(); while(iterator.hasNext()){ String fruit = iterator.next(); System.out.println("Processing "+fruit); //correct way of structural modification of Set if("Orange".equals(fruit)) iterator.remove(); } System.out.println("fruits set after iteration = "+fruits); }}

Above HashSet iterator example will not throw exception and you will get below output.

上面的HashSet迭代器示例不会引发异常,您将得到下面的输出。

Processing AppleProcessing MangoProcessing OrangeProcessing Bananafruits set after iteration = [Apple, Mango, Banana]

Java HashSet到数组示例 (Java HashSet to Array Example)

Sometimes we have to convert HashSet to array and vice versa. Below is a simple program showing correct way to convert HashSet to array and then Array to HashSet.

有时我们必须将HashSet转换为array,反之亦然。 下面是一个简单的程序,显示了将HashSet转换为array,然后将Array转换为HashSet的正确方法。

package com.journaldev.examples;import java.util.Arrays;import java.util.HashSet;import java.util.Set;public class HashSetToArrayExample {	public static void main(String[] args) {		Set
ints = new HashSet<>(); for(int i=0; i<10; i++){ ints.add(i); } System.out.println("ints set = "+ints); // set to array example Integer[] intArray = new Integer[ints.size()]; intArray = ints.toArray(intArray); System.out.println("intArray = "+Arrays.toString(intArray)); ints.remove(0);ints.remove(1); System.out.println("intArray = "+Arrays.toString(intArray)); //array to set example ints = new HashSet<>(Arrays.asList(intArray)); System.out.println("ints from array = "+ints); ints.remove(0);ints.remove(1); System.out.println("ints from array after remove = "+ints); System.out.println("intArray = "+Arrays.toString(intArray)); }}

Output of above HashSet to array example is;

以上HashSet的输出到数组示例为;

ints set = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]intArray = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]intArray = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]ints from array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]ints from array after remove = [2, 3, 4, 5, 6, 7, 8, 9]intArray = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Java HashSet列出示例 (Java HashSet to List Example)

There is not much difference between Set and , but sometimes we have to convert from Set to List or List to Set. Below is a simple example showing correct way to convert Set to List and then List to Set in java.

Set和之间没有太大区别,但是有时我们必须从Set转换为List或List转换为Set。 下面是一个简单的示例,显示了在Java中将Set转换为List然后将List转换为Set的正确方法。

package com.journaldev.examples;import java.util.ArrayList;import java.util.HashSet;import java.util.List;import java.util.Set;public class HashSetToListExample {	public static void main(String[] args) {		Set
vowels = new HashSet<>(); vowels.add("a"); vowels.add("e"); vowels.add("i"); //set to list example List
vowelsList = new ArrayList<>(vowels); System.out.println("vowels set = "+vowels); System.out.println("vowelsList = "+vowelsList); vowels.add("o"); vowelsList.add("a");vowelsList.add("u"); System.out.println("vowels set = "+vowels); System.out.println("vowelsList = "+vowelsList); //list to set example vowels = new HashSet<>(vowelsList); System.out.println("vowels set = "+vowels); }}

Output of above java Set to List example program is;

上面的java Set to List示例程序的输出是;

vowels set = [a, e, i]vowelsList = [a, e, i]vowels set = [a, e, i, o]vowelsList = [a, e, i, a, u]vowels set = [a, e, u, i]

Java HashSet equals()和hashCode()方法 (Java HashSet equals() and hashCode() methods)

HashSet utilise HashMap for storing it’s elements. HashSet works with equals() and hashCode() method to check for duplicate element when you try to add an element. Let’s see what happens if you Set object doesn’t provide equals() method implementation.

HashSet利用HashMap来存储其元素。 当您尝试添加元素时,HashSet与equals()和hashCode()方法一起使用以检查重复的元素。 让我们看看如果您的Set对象不提供equals()方法的实现会发生什么。

package com.journaldev.examples;import java.util.HashSet;import java.util.Set;public class HashSetEqualsMethodImportance {	public static void main(String[] args) {		Set
emps = new HashSet<>(); emps.add(new Emp(1,"Pankaj")); emps.add(new Emp(2, "David")); emps.add(new Emp(1, "Pankaj")); System.out.println(emps); }}class Emp { private String name; private int id; public Emp(int i, String n) { this.id = i; this.name = n; } @Override public String toString(){ return "{"+id+","+name+"}"; }}

When we run above program, we get below output for Set elements.

当我们在程序上方运行时,将在Set元素的输出下方得到结果。

[{2,David}, {1,Pankaj}, {1,Pankaj}]

So it looks like we were able to store duplicate elements in the Set. Actually not, it’s happening because Emp class doesn’t define equals() method, so Object class equals() method implementation is used. Object class defines equals() method like below.

因此,看来我们能够在Set中存储重复的元素。 实际上不是这样,因为Emp类没有定义equals()方法,所以使用Object类的equals()方法实现。 对象类定义如下的equals()方法。

public boolean equals(Object obj) {        return (this == obj);    }

So when adding a new element, object reference is being checked rather than content. Hence we have objects with duplicate content, however they are having different references. Let’s see what happens when we define hashCode() and equals() methods in the Emp class.

因此,在添加新元素时,将检查对象引用而不是内容。 因此,我们的对象具有重复的内容,但是它们具有不同的引用。 让我们看看在Emp类中定义hashCode()和equals()方法时会发生什么。

package com.journaldev.examples;import java.util.HashSet;import java.util.Set;public class HashSetEqualsMethodImportance {	public static void main(String[] args) {		Set
emps = new HashSet<>(); emps.add(new Emp(1,"Pankaj")); emps.add(new Emp(2, "David")); emps.add(new Emp(1, "Pankaj")); System.out.println(emps); Emp e = new Emp(3, "Lisa"); emps.add(e); System.out.println(emps); //set values to make it duplicate e.setId(1); System.out.println(emps); e.setName("Pankaj"); System.out.println(emps); }}class Emp { private String name; private int id; public Emp(int i, String n) { this.setId(i); this.setName(n); } @Override public boolean equals(Object obj){ if(obj == null || !(obj instanceof Emp)) return false; Emp e = (Emp) obj; if(e.getId() == this.getId() && this.getName().equals(e.getName())) return true; return false; } @Override public int hashCode(){ return getId(); } @Override public String toString(){ return "{"+getId()+","+getName()+"}"; } public String getName() { return name; } public int getId() { return id; } public void setName(String name) { this.name = name; } public void setId(int id) { this.id = id; }}

This time our program produces following output.

这次我们的程序产生以下输出。

[{1,Pankaj}, {2,David}][{1,Pankaj}, {2,David}, {3,Lisa}][{1,Pankaj}, {2,David}, {1,Lisa}][{1,Pankaj}, {2,David}, {1,Pankaj}]

Notice that HashSet was able to check for duplicate when we tried to add an element. But we can change the object values using setter methods and make it duplicate. It worked because there is no operation done on Set. This is why Immutable objects works better with Set and Map.

请注意,当我们尝试添加元素时,HashSet能够检查重复项。 但是我们可以使用setter方法更改对象值并将其复制。 之所以起作用,是因为对Set没有执行任何操作。 这就是为什么不可变对象与Set和Map更好地工作的原因。

That’s all for Java HashSet example tutorial, I hope that all the important things are covered for HashSet in Java. If I have missed anything, please let me know through comments and I will try to add that too.

Java HashSet示例教程就这些了,我希望Java中的HashSet涵盖所有重要的内容。 如果我错过了任何事情,请通过评论告知我,我也会尝试添加。

翻译自:

java中hashset

转载地址:http://rqlzd.baihongyu.com/

你可能感兴趣的文章
小D课堂 - 零基础入门SpringBoot2.X到实战_第10节 SpringBoot整合定时任务和异步任务处理_42、SpringBoot常用定时任务配置实战...
查看>>
小D课堂 - 零基础入门SpringBoot2.X到实战_第9节 SpringBoot2.x整合Redis实战_39、SpringBoot2.x整合redis实战讲解...
查看>>
小D课堂 - 零基础入门SpringBoot2.X到实战_第14节 高级篇幅之SpringBoot多环境配置_59、SpringBoot多环境配置介绍和项目实战...
查看>>
小D课堂 - 零基础入门SpringBoot2.X到实战_第10节 SpringBoot整合定时任务和异步任务处理_41、SpringBoot定时任务schedule讲解...
查看>>
小D课堂 - 零基础入门SpringBoot2.X到实战_第10节 SpringBoot整合定时任务和异步任务处理_43、SpringBoot2.x异步任务实战(核心知识)...
查看>>
小D课堂 - 新版本微服务springcloud+Docker教程_1_01课程简介
查看>>
小D课堂 - 零基础入门SpringBoot2.X到实战_第11节 Logback日志框架介绍和SpringBoot整合实战_45、SpringBoot2.x日志讲解和Logback配置实战...
查看>>
小D课堂 - 新版本微服务springcloud+Docker教程_1_02技术选型
查看>>
小D课堂 - 新版本微服务springcloud+Docker教程_汇总
查看>>
小D课堂 - 新版本微服务springcloud+Docker教程_2_01传统架构演进到分布式架构
查看>>
小D课堂 - 新版本微服务springcloud+Docker教程_2_02 微服务核心基础讲解
查看>>
小D课堂 - 新版本微服务springcloud+Docker教程_2_04微服务下电商项目基础模块设计...
查看>>
小D课堂 - 新版本微服务springcloud+Docker教程_3-01 什么是微服务的注册中心
查看>>
小D课堂 - 新版本微服务springcloud+Docker教程_3-03CAP原理、常见面试题
查看>>
小D课堂 - 新版本微服务springcloud+Docker教程_3-04 SpringCloud微服务核心组件Eureka介绍和闭源后影响...
查看>>
小D课堂 - 新版本微服务springcloud+Docker教程_3-05 服务注册和发现Eureka Server搭建实战...
查看>>
小D课堂 - 新版本微服务springcloud+Docker教程_3-06 服务注册和发现之Eureka Client搭建商品服务实战...
查看>>
小D课堂 - 新版本微服务springcloud+Docker教程_3-07 Eureka服务注册中心配置控制台问题处理...
查看>>
小D课堂 - 新版本微服务springcloud+Docker教程_4-01 常用的服务间调用方式讲解
查看>>
小D课堂 - 新版本微服务springcloud+Docker教程_4-02 微服务调用方式之ribbon实战 订单调用商品服务...
查看>>