添加微信:code_7steps,备注“进群”,邀请你加入大牛云集的技术交流群!
在编程开发过程中,经常会涉及到键值对的存取,在Java中比较具有代表性的有HashMap
和TreemMap
。
这两种Map接口的实现广泛的应用于存储键值对,支持每天在数据集上的各种操作,增、删、改、查。
本文,就来通过示例详细介绍一下TreeMap
和HashMap
之间的核心异同点。
在Java中,所有Map实现都将存储键值对,但基于实现的差异很小。与TreeMap相比,HashMap在收集框架的日常开发中得到了广泛使用。两者都使用内部存储桶概念,但是当任何存储桶分区变大时,它都会转换为TreeNode结构。
HashMap
和TreeMap
之间的相似之处
了解两个类的差异之前,首先看一下它们之间的共同点。
这两个类具有如下共同点:
HashMap
和TreeMap
类实现Map<K, V>
,Cloneable
,Serializable
接口,并扩展AbstractMap<K, V>
类- 两者都基于键存储值
- 键值保证始终唯一,如果我们再次添加相同的键,则旧值将被新值替换
- 都不是不是线程安全的,因为如果在迭代过程中修改了原始Map,则会引发运行时异常
HashMap
示例
在下面的示例中,我主要实现了如下几个功能:
- 我们使用
put()
方法向HashMap
添加了几个值 - 输出
HashMap
的所有值 - 使用迭代器打印值
- 从原始
HashMap
中删除了键“0333” - 从
HashMap
中删除键会产生异常
示例代码:
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
publicclass HashMapExamples {
public static void main(String[] args) {
Map<String, String> hashMap = new HashMap<>();
hashMap.put("0111", "one's");
hashMap.put("0222", "two's");
hashMap.put("0333", "three's");
hashMap.put("0444", "four's");
hashMap.put("0111", "one's modified");
System.out.println("HashMap values are - " + hashMap);
System.out.println("Iterating Hashmap and modifying the values");
Set<String> keys = hashMap.keySet();
Iterator<String> iterator = keys.iterator();
while (iterator.hasNext()) {
String key = iterator.next();
System.out.println("key - " + key + ", value - " + hashMap.get(key));
if (key == "0333") {
hashMap.remove(key);
}
}
}
}
复制代码
输出:
HashMap values are - {0111=one's modified, 0222=two's, 0333=three's, 0444=four's}
Iterating Hashmap and modifying the values
key - 0111, value - one's modified
key - 0222, value - two's
key - 0333, value - three's
Exception in thread "main" java.util.ConcurrentModificationException
at java.base/java.util.HashMap$HashIterator.nextNode(HashMap.java:1490)
at java.base/java.util.HashMap$KeyIterator.next(HashMap.java:1513)
at com.javaprogramto.collections.hashmap.HashMapExamples.main(HashMapExamples.java:29)
复制代码
TreeMap
示例
对于TreeMap
采用相似的示例,在下面的示例中,我们使用put()
方法向TreeMap添加了一些值。接下来,按排序顺序打印TreeMap
的所有值。进一步尝试使用迭代器打印值,并从TreeMap
中删除了键“ 0333”。从TreeMap
中删除键会产生运行时异常。
示例代码:
package com.javaprogramto.collections.treemap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
publicclass TreeMapExamples {
public static void main(String[] args) {
Map<String, String> treeMap = new TreeMap<>();
treeMap.put("0111", "one's");
treeMap.put("0222", "two's");
treeMap.put("0333", "three's");
treeMap.put("0444", "four's");
treeMap.put("0111", "one's modified");
System.out.println("treeMap values are - " + treeMap);
System.out.println("Iterating treeMap and modifying the values");
Set<String> keys = treeMap.keySet();
Iterator<String> iterator = keys.iterator();
while (iterator.hasNext()) {
String key = iterator.next();
System.out.println("key - " + key + ", value - " + treeMap.get(key));
if (key == "0333") {
treeMap.remove(key);
}
}
}
}
复制代码
输出:
treeMap values are - {0111=one's modified, 0222=two's, 0333=three's, 0444=four's}
Iterating treeMap and modifying the values
key - 0111, value - one's modified
key - 0222, value - two's
key - 0333, value - three's
Exception in thread "main" java.util.ConcurrentModificationException
at java.base/java.util.TreeMap$PrivateEntryIterator.nextEntry(TreeMap.java:1208)
at java.base/java.util.TreeMap$KeyIterator.next(TreeMap.java:1262)
at com.javaprogramto.collections.treemap.TreeMapExamples.main(TreeMapExamples.java:29)
复制代码
HashMap
和TreeMap
之间的区别
以下是这两个类之间的主要区别:
TreeMap
实现NavigableMap接口而不是Map接口HashMap
是基于哈希表实现的,TreeMap
是基于树结构(例如红黑树)实现的HashMap
仅允许一个空键和多个空值,TreeMap
不允许空键,但允许空值HashMap
不对键进行排序,TreeMap
会对键进行排序HashMap
比TreeMap
快,因为hashmap不会排序,因此它可以使用put()
和get()
方法以恒定的O(1)时间时间复杂度轻松访问插入和检索HashMap
使用equals()
方法进行重复键比较,但对于TreeMap
,键是根据compareTo()
方法进行比较和排序的
结语
在本文中,通过简单的示例介绍了HashMap
和`TreeMap两个类之间的异同点,关于两个人,还有很多内容值得了解和学习,如果感兴趣可以针对性的自行查阅相关资料。
干货推荐
为了方便大家,我花费了半个月的时间把这几年来收集的各种技术干货整理到一起,其中内容包括但不限于Python、机器学习、深度学习、计算机视觉、推荐系统、Linux、工程化、Java,内容多达5T+,所有干货送给大家,希望能够点赞支持一下!
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END