如何决定使用 HashMap 还是 TreeMap?
问:如何决定使用 hashmap 还是 treemap?
介绍
treemap<k,v>
的key值是要求实现java.lang.comparable
,所以迭代的时候treemap默认是按照key值升序排序的;treemap的实现是基于红黑树结构。适用于按自然顺序或自定义顺序遍历键(key)。
hashmap<k,v>
的key值实现散列hashcode()
,分布是散列的、均匀的,不支持排序;数据结构主要是桶(数组),链表或红黑树。适用于在map中插入、删除和定位元素。
结论
如果你需要得到一个有序的结果时就应该使用treemap(因为hashmap中元素的排列顺序是不固定的)。除此之外,由于hashmap有更好的性能,所以大多不需要排序的时候我们会使用hashmap。
拓展
1、hashmap 和 treemap 的实现
hashmap:基于哈希表实现。使用hashmap要求添加的键类明确定义了hashcode()
和equals()
[可以重写hashcode()
和equals()
],为了优化hashmap空间的使用,您可以调优初始容量和负载因子。
- hashmap(): 构建一个空的哈希映像
- hashmap(map m): 构建一个哈希映像,并且添加映像m的所有映射
- hashmap(int initialcapacity): 构建一个拥有特定容量的空的哈希映像
- hashmap(int initialcapacity, float loadfactor): 构建一个拥有特定容量和加载因子的空的哈希映像
treemap:基于红黑树实现。treemap没有调优选项,因为该树总处于平衡状态。
- treemap():构建一个空的映像树
- treemap(map m): 构建一个映像树,并且添加映像m中所有元素
- treemap(comparator c): 构建一个映像树,并且使用特定的比较器对关键字进行排序
- treemap(sortedmap s): 构建一个映像树,添加映像树s中所有映射,并且使用与有序映像s相同的比较器排序
2、hashmap 和 treemap 都是非线程安全
hashmap继承abstractmap抽象类,treemap继承自sortedmap接口。
abstractmap抽象类:覆盖了equals()和hashcode()方法以确保两个相等映射返回相同的哈希码。如果两个映射大小相等、包含同样的键且每个键在这两个映射中对应的值都相同,则这两个映射相等。映射的哈希码是映射元素哈希码的总和,其中每个元素是map.entry接口的一个实现。因此,不论映射内部顺序如何,两个相等映射会报告相同的哈希码。
sortedmap接口:它用来保持键的有序顺序。sortedmap接口为映像的视图(子集),包括两个端点提供了访问方法。除了排序是作用于映射的键以外,处理sortedmap和处理sortedset一样。添加到sortedmap实现类的元素必须实现comparable接口,否则您必须给它的构造函数提供一个comparator接口的实现。treemap类是它的唯一一个实现。
3、treemap中默认是按照升序进行排序的,如何让他降序
通过自定义的比较器来实现
定义一个比较器类,实现comparator接口,重写compare方法,有两个参数,这两个参数通过调用compareto进行比较,而compareto默认规则是:
- 如果参数字符串等于此字符串,则返回 0 值;
- 如果此字符串小于字符串参数,则返回一个小于 0 的值;
- 如果此字符串大于字符串参数,则返回一个大于 0 的值。
自定义比较器时,在返回时多添加了个负号,就将比较的结果以相反的形式返回,代码如下:
static class mycomparator implements comparator{ @override public int compare(object o1, object o2) { // todo auto-generated method stub string param1 = (string)o1; string param2 = (string)o2; return -param1.compareto(param2); } }
之后,通过mycomparator类初始化一个比较器实例,将其作为参数传进treemap的构造方法中:
mycomparator comparator = new mycomparator(); map<string,string> map = new treemap<string,string>(comparator);
这样,我们就可以使用自定义的比较器实现降序了
public class maptest { public static void main(string[] args) { //初始化自定义比较器 mycomparator comparator = new mycomparator(); //初始化一个map集合 map<string,string> map = new treemap<string,string>(comparator); //存入数据 map.put("a", "a"); map.put("b", "b"); map.put("f", "f"); map.put("d", "d"); map.put("c", "c"); map.put("g", "g"); //遍历输出 iterator iterator = map.keyset().iterator(); while(iterator.hasnext()){ string key = (string)iterator.next(); system.out.println(map.get(key)); } } static class mycomparator implements comparator{ @override public int compare(object o1, object o2) { // todo auto-generated method stub string param1 = (string)o1; string param2 = (string)o2; return -param1.compareto(param2); } } }
上一篇: OPATCH在线补丁
推荐阅读
-
Linux如何使用shell查看Linux是32位还是64
-
如何决定使用 HashMap 还是 TreeMap?
-
Apache Commons Logging 是如何决定使用哪个日志实现类的
-
Apache Commons Logging 是如何决定使用哪个日志实现类的
-
android和ios调用php写的接口如何判断用户使用的是安卓还是苹果
-
Linux如何使用shell查看Linux是32位还是64
-
如何决定使用 HashMap 还是 TreeMap?
-
android和ios调用php写的接口如何判断用户使用的是安卓还是苹果
-
面试常问:如何决定使用 HashMap 还是 TreeMap
-
html元素如何确定使用id还是class选择器?(示例)