映射
映射(Map)是一种数据结构,它存储键值对(key-value pair)的集合。映射中的每一个元素都包含一个键和一个值,键是唯一的,而值可以是任何类型的数据。Java提供了多种实现映射的接口和类,其中最常用的接口是java.util.Map
。
映射的类型
映射(Maps)用于存储键值对,常见的实现有 HashMap 和 TreeMap。
在学映射前我们需要知道Hash是什么
哈希函数是一种将任意长度的数据(通常称为“消息”或“输入值”)映射为固定长度数据的函数。
Hash函数特性:
确定性:相同的输入总是产生相同的输出。
高效性:计算哈希值的时间复杂度应该相对较低。
雪崩效应(Avalanche Effect):输入数据的微小变化应该导致哈希值的显著变化。
抗碰撞性:找到两个不同输入但具有相同哈希值的难度应该非常大(在计算上是不可行的)。
哈希表(Hash Table):
哈希表是一种基于哈希函数的数据结构,它使用哈希函数将键映射到数组中的索引,以便快速访问、插入和删除元素。哈希表在许多编程语言的标准库中都有实现,并被广泛用于实现缓存、数据库索引等。
哈希算法(Hashing Algorithm):
哈希算法是用于计算哈希值的特定算法。不同的哈希算法具有不同的特性和用途。例如,MD5 和 SHA-256 是两种广泛使用的密码哈希算法,用于生成数据的唯一标识符(如文件校验和)。而像 MurmurHash 和 CityHash 这样的哈希算法则更多地被用于哈希表和其他数据结构。
哈希碰撞(Hash Collision):
哈希碰撞是指两个或更多个不同的输入值产生了相同的哈希值。虽然在设计良好的哈希函数中,哈希碰撞是罕见的,但在实际应用中仍然可能发生。因此,处理哈希碰撞是哈希表和其他基于哈希的数据结构必须考虑的问题。
分布式哈希表(Distributed Hash Table, DHT):
分布式哈希表是一种分布式的键值存储系统,它使用哈希函数将键映射到不同的节点上,从而实现数据的分布式存储和访问。DHT 通常用于构建去中心化的对等网络(P2P)应用,如文件共享、即时通讯等。
Hash碰撞怎么解决
链地址法(Chaining):
在链地址法中,哈希表的每个位置都是一个链表的头节点。当发生碰撞时,具有相同哈希值的键值对被链接到同一个链表中。这种方法也称为哈希链。
映射的实现
Map<String, Integer> hashMap = new HashMap<>();
Map<String, Integer> treeMap = new TreeMap<>();
HashMap:
特点: 基于哈希表实现的键值对存储结构。
优点: 高效的查找、插入和删除操作。
缺点: 无序,不保证顺序。
HashMap<Integer,String> hashMap = new HashMap<>();
hashMap.put(1,"gg");
hashMap.put(2,"g");
//添加键值对
hashMap.put(3,"ggg");
//删除键值对
hashMap.remove(3);
//清理键值对
hashMap.clear();
//返回null
System.out.println(hashMap.get(1));
TreeMap:
特点: 基于红黑树实现的有序键值对存储结构。
优点: 有序,支持按照键的顺序遍历。
缺点: 插入和删除除
public class TreeMapExample {
public static void main(String[] args) {
// 创建一个 TreeMap 实例
TreeMap<String, Integer> treeMap = new TreeMap<>();
// 向 TreeMap 中添加元素
treeMap.put("Apple", 10);
treeMap.put("Banana", 5);
treeMap.put("Cherry", 20);
treeMap.put("Date", 15);
// 遍历 TreeMap 并打印元素
for (Map.Entry<String, Integer> entry : treeMap.entrySet()) {
System.out.println("Key: " + entry.getKey() + ", Value: " + entry.getValue());
}
// 获取并打印第一个键
System.out.println("First key: " + treeMap.firstKey());
// 获取并打印最后一个键
System.out.println("Last key: " + treeMap.lastKey());
// 获取并打印小于指定键的最大键
System.out.println("Key below 'Cherry': " + treeMap.lowerKey("Cherry"));
// 获取并打印大于或等于指定键的最小键
System.out.println("Key above or equal to 'Banana': " + treeMap.ceilingKey("Banana"));
// 获取并打印子映射(范围视图)
System.out.println("Submap from 'Banana' to 'Cherry': " + treeMap.subMap("Banana", "Cherry"));
}
}