1. Map顺序问题
对map里的元素进行遍历时,发现元素的顺序无法预料:
Map<TopicNLPEnum, List<String>> map = new HashMap<>();
map.put(TopicNLPEnum.SIMILAR, Arrays.asList("小说1", "言情1", "历史1"));
map.put(TopicNLPEnum.RELATIVE, Arrays.asList("小说3", "言情3", "历史3"));
map.put(TopicNLPEnum.ORIGIN, Arrays.asList("小说", "言情", "历史"));
map.put(TopicNLPEnum.TAGS, Arrays.asList("小说2", "言情2", "历史2"));
map.entrySet().forEach(entry -> System.out.println(entry.getValue()));
输出:
[小说2, 言情2, 历史2]
[小说1, 言情1, 历史1]
[小说3, 言情3, 历史3]
[小说, 言情, 历史]
2. 解决办法
- 使用LinkedHashMap(保留插入时的顺序)
Map<TopicNLPEnum, List<String>> map = new LinkedHashMap();
- 使用TreeMap(按照Key的大小来排序;可以指定Comparator来确定key的大小)
Comparator<TopicNLPEnum> comp = (o1, o2) -> o2.getScore() - o1.getScore();
Map<TopicNLPEnum, List<String>> map = new TreeMap(comp);
- 使用sort方法,参见java8 map 使用Comparator排序
3. HashMap,LinkedHashMap, TreeMap三者的区别
HashMap | TreeMap | LinkedHashMap | |
---|---|---|---|
iterator order | 没有顺序 | 根据key排序 | 插入时的顺序 |
get, put, remove 操作 | O(1) | O(log(n)) | O(1) |
实现的接口 | Map | NavigableMap, Map, SortedMap | Map |
内部实现 | buckets | Red-Black Tree | Double-linked buckets |
null | 允许最多一个null key,和多个null value | 不允许null key,但是可以有多个null value | 和HashMap一致 |
performance | 占有较大的内存; 当key的hash重复度较大时,会造成collisions,这样会降低查询的速度,最坏的情况有O(n)的复杂度, 当collision比较大时,buckets会转化成类似与TreeMap的结构,降低复杂度到O(log(n)); 当发生collision的数组的长度大于阈值时,还会自动扩容,这样也会造资源消耗 | 和HashMap比起来,TreeMap更加节约内存;当不清楚需要存储多少数据时,可以使用TreeMap |