Java 中的 HashMap、HashSet 和 Hashtable
Java 的 Collection
接口为我们提供了各种接口和类来实现各种数据结构和算法。
本教程将讨论 Java 中的 HashMap
、HashSet
和 Hashtable
。
首先,让我们了解一下一般的哈希表是什么。
我们可以使用哈希表以键值对模式存储元素,这意味着每个键都有一个与之关联的值。键是用于索引值的唯一值。值是与相应键相关的数据。
哈希表数据结构遵循哈希的概念,其中使用键处理新索引。然后将与该键对应的元素存储在索引中。这就是哈希的概念。
让 h(x)
是散列函数,而 k
是一个键,那么 h(k)
将给出一个新的索引来存储与 k
链接的元素。
Java HashMap
HashMap
是一类 Java 的集合框架,它为我们提供了哈希表数据结构。它将元素存储为键值对,其中键是映射上与特定值配对的唯一标识符。HashMap
类实现了 Map 接口,它进一步扩展了 Collections 接口。
HashMap
是不同步的,这意味着它不是线程安全的。我们可以使用多个线程访问它并同时修改它。它可以在外部成为线程安全的。
HashMap
的另一个特点是它可以保存一个空的键或值对。
例如,
import java.util.HashMap;
public class Main {
public static void main(String[] args) {
HashMap<String, Integer> h = new HashMap<>();
h.put("One", 1);
h.put("Two", 2);
h.put("Three", 3);
System.out.println(h);
}
}
输出:
HashMap: {One=1, Two=2, Three=3}
Java Hashtable
Java 的 Hashtable
类实现了哈希表数据结构。与 HashMap
类似,它也将元素存储为键值对。但它与 HashMap
不同,因为它是同步的。它将键值对存储在哈希表中。它实现了 Map 接口。
首先,在 Hashtable
中,我们将对象指定为键,并将其值作为一对。然后对键进行散列,然后我们将得到的散列码用作存储在表中的值的索引。
因此,与 Hashtable
相关的问题是同步每个方法调用相对而言不是无关紧要的。不是每次都需要。因此,为了克服这个问题,集合框架的作者提出了一个名为 HashMap
(它还阐明它映射元素)的新类,它是非同步的。
如果不想使用方法级同步,可以跳过 Hashtable
并使用 Collections.synchronizedMap()
将 Map 转换为同步 Map。或者,我们可以使用 ConcurrentHashMap
,根据其文档,它提供与 Hashtable
相同的功能,但具有更好的性能和一些附加功能。
例如,
import java.io.*;
import java.util.*;
public class Main {
public static void main(String args[])
{
Hashtable<Integer, String> h = new Hashtable<>();
h.put(1, "one");
h.put(2, "two");
h.put(3, "three");
System.out.println(h);
}
}
输出:
{3=three, 2=two, 1=one}
Java HashSet
HashSet
是一类 Java 的集合框架,它为我们提供了哈希表数据结构的实现(就像 HashMap
)。尽管如此,它还是实现了 Set
接口(与 HashMap
不同),它进一步扩展了 Collections 接口。这通常在我们不需要将键映射到值对时使用。
HashSet
与 Hashtable
的不同之处在于 HashSet
不能保存重复值。键值对是唯一的。就功能而言,HashSet
与 HashMap
没有任何共同之处,但它恰好在内部使用了 HashMap
来实现 Set 接口。
例如,
import java.util.HashSet;
public class Main {
public static void main(String[] args) {
HashSet<Integer> h = new HashSet<>();
h.add(5);
h.add(10);
h.add(15);
System.out.println(h);
}
}
输出:
[5, 10, 15]