1. 简介
写在前面:一般认为,线程同步使用Hashtable;线程非同步使用HashMap。
当然,一般来说HashMap都优先于Hashtable,HashMap功能更多,且保护线程安全也不麻烦
第一点:
- Hashtable是基于:Dictionary类的
- HashMap是Java 1.2引进的Map接口的实现。
第二点:
- Hashtable:任何方法都是同步的,所以效率会较低,可以直接在多线程中使用
- HashMap:是非同步的效率更高
HashMap在多线程中使用需要保护线程安全。(如利用Collections类的静态的synchronizedMap()方法。创建一个线程安全的Map对象)
第三点:
- HashMap:允许空值,空值可作为key或value
也就是说存在两种情况:key不存在;value为空。那么get()将返回null。
可以使用containKey()方法来区别这两种情况。
2. HashMap
- 1、HashMap 是一个散列表,它存储的内容是键值对(key-value)映射
- 2、HashMap 实现了 Map 接口,根据键的 HashCode 值存储数据,具有很快的访问速度,最多允许一条记录的键为 null,不支持线程同步
- 3、HashMap 是无序的,即不会记录插入的顺序
- 4、HashMap 继承于AbstractMap,实现了 Map、Cloneable、java.io.Serializable 接口
- 5、HashMap 的 key 与 value 类型可以相同也可以不同,可以是字符串(String)类型的 key 和 value,也可以是整型(Integer)的 key 和字符串(String)类型的 value
Map<String,String> map = Map.of(“a”,“aa”,“b”,“bb”)
Map<Integer,String> map = Map.of(1,“aa”,33,“bb”) - 6、 HashMap 中的元素实际上是对象,不能直接使用基本类型,一些常见的基本类型可以使用它的包装类
- 7、 HashMap 类位于 java.util 包中,使用前需要引入:import java.util.HashMap;
Java HashMap方法:
举个例子:
public class HashMapTest {
public static void main(String[] args) {
// 创建 HashMap 对象 Sites
HashMap<Integer, String> Sites = new HashMap<Integer, String>();
// 添加键值对
Sites.put(1, "jia");
Sites.put(22, "da");
Sites.put(4, "jun");
System.out.println(Sites);
//访问元素
String jun = Sites.get(4);
System.out.println(jun);
//删除元素
Sites.remove(4);
System.out.println(Sites);
//迭代 HashMap
for (Integer i : Sites.keySet()) {
int key = i;
String value = Sites.get(i);
System.out.println("key:" + key + " value:" + value);
}
}
}
3. HashSet
- HashSet 基于 HashMap 来实现的,是一个不允许有重复元素的集合
- HashSet 允许有 null 值
- HashSet 是无序的,即不会记录插入的顺序
- HashSet 不是线程安全的
- HashSet 实现了 Set 接口
HashSet类常用方法:
set.toArray()【0】方法:将set集合转为数组
class Solution {
public int singleNumber(int[] nums) {
Set<Integer> set = new HashSet<>();
for (int num : nums) {
if (!set.add(num)) {
//如果添加失败,说明这个值
//在集合Set中存在,我们要
//把他给移除掉
set.remove(num);
}
}
//最终集合Set中只有一个元素,我们直接返回
return (int) set.toArray()[0];
}
}