本文共 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接口。
Some of the important points about HashSet in java are;
Java中有关HashSet的一些重要要点是:
Collections.synchronizedSet
method at the cost of performance. You can also use CopyOnWriteArraySet
concurrency class for thread safety. HashSet不是线程安全的。 您可以使用Collections.synchronizedSet
方法获取线程安全的HashSet,但会降低性能。 您也可以将CopyOnWriteArraySet
并发类用于线程安全。 Java HashSet provides four constructors.
Java HashSet提供了四个构造函数。
Below code snippet is showing all these HashSet constructors example usage.
下面的代码片段显示了所有这些HashSet构造函数示例用法。
Setset = 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<>());
Some of the useful HashSet methods are;
一些有用的HashSet方法是:
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) { Setfruits = 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 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) { Setfruits = 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) { Setfruits = 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]
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) { Setints = 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]
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) { Setvowels = 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]
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) { Setemps = 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) { Setemps = 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/