# Java `ConcurrentHashSet`示例

> 原文： [https://javatutorial.net/java-concurrenthashset-example](https://javatutorial.net/java-concurrenthashset-example)

Java 8 最终允许我们（程序员）在 Java 中创建线程安全的[`ConcurrentHashSet`](https://javatutorial.net/java-hashset-example)。 在此之前，这根本是不可能的。 有一些变种试图简化上述类的实现，其中之一就是使用带有虚拟值[`ConcurrentHashMap`](https://javatutorial.net/java-hashmap-example) 。 但是，您可能已经猜到，[`ConcurrentHashMap`](https://javatutorial.net/java-hashmap-example) 的所有即兴创作都有其局限性和风险。

![java-featured-image](img/e0db051dedc1179e7424b6d998a6a772.jpg)

Java 8 允许我们使用`keySet(defaultVal)`和`newKeySet()`方法来返回 Set，这恰好是一个合适的集合。 这样可以访问用户可以使用的许多必要功能：`contains()`，`remove()`等。 **注意**： 这些方法在`ConcurrentHashMap`中可用，而不是在`ConcurrentMap`接口中可用， 意味着必须创建`ConcurrentHashMap`类型的变量，并将其用作引用。 另一种方法是对象的简单转换。

Java 并发 API 中包含许多`Collection`类，例如`ArrayList`的`CopyOnArrayList`，`HashMap`的`ConcurrentHashMap`和`HashSet`的`CopyOnWriteArraySet`。 但是，尽管有所有这些示例，但没有类似`ConcurrentHashSet`的东西。 许多开发人员说，他们可以使用具有相同值的`ConcurrentHashMap`来实现所需的集合，但是这种方法的问题在于，您拥有的是映射而不是集合。 因此，这将导致无法使用伪值对`ConcurrentHashMap`执行设置操作。 简而言之，它不是`Set`。

还有其他尝试创建`ConcurrentHashSet`的即兴创作，但现在它们都已过去，因为 Java 8 添加了`newKeySet()`，它返回由`ConcurrentHashMap`支持的`Set`。

### 如何在 Java 8 中创建`ConcurrentHashSet`

```java
ConcurrentHashMap<String, Integer> example = new ConcurrentHashMap<>(); 
Set<String> exampleSet = example.newKeySet(); 
exampleSet.add("example"); 
exampleSet.add("example2");
exampleSet.contains("example2"); 
exampleSet.remove("example"); 

```

在上面的示例中，我们创建了集合，并向其中添加了 2 个元素，检查它是否包含某个元素并删除了某个元素。

**注意**： 这是在 Java 中创建线程安全`Set`的唯一方法。

### Java 程序使用`java.util.concurrent.ConcurrentHashMap`类上添加的新方法创建`ConcurrentHashSet`。

```java
import java.util.Set; 
import java.util.concurrent.ConcurrentHashMap; 

public class Example { 
   public static void main(String[] args) throws Exception { 
      ConcurrentHashMap shoesCost = new ConcurrentHashMap<>(); 
      shoesCost.put("Nike", 80); 
      shoesCost.put("Adidas", 40); 
      shoesCost.put("Reebok", 76); 

      Set shoeCostSet = shoesCost.keySet(); 

      shoeCostSet = shoesCost.newKeySet(); 
      System.out.println("before adding element into concurrent set: " + shoeCostSet);
      shoeCostSet.add("Puma"); 
      System.out.println("after adding element into concurrent set: " + shoeCostSet); 
      shoeCostSet.contains("Adidas"); 
      shoeCostSet.remove("Reebok"); 
  } 
} 

```

**输出**：

```java
before adding an element into the concurrent set: [Nike, Adidas, Reebok] 
after adding an element into the concurrent set: [Nike, Adidas, Reebok, Puma] 

```