我有一个列表,我将其转换为地图以进行一些工作。之后,我将地图再次转换回列表,但这次订单是随机的。我需要在第二个列表中保留相同的初始订单。
显而易见的原因是HashMap没有维护秩序。但我需要做一些事情才能做到。我无法更改Map实现。我该怎么做?
考虑给定的代码:
import java.util.*;
public class Dummy {
public static void main(String[] args) {
System.out.println("Hello world !");
List<String> list = new ArrayList<String>();
list.add("A");list.add("B");list.add("C");
list.add("D");list.add("E");list.add("F");
Map<String,String> map = new HashMap<String, String>();
for(int i=0;i<list.size();i=i+2)
map.put(list.get(i),list.get(i+1));
// Use map here to do some work
List<String> l= new ArrayList<String>();
for (Map.Entry e : map.entrySet()) {
l.add((String) e.getKey());
l.add((String) e.getValue());
}
}
}
对于前 - 最初,当我打印列表元素时,它打印出来
A B C D E F
现在,当我打印List l
的元素时,它会打印出来
E F A B C D
答案 0 :(得分:29)
HashMap
本身不会维护广告订单 - 但LinkedHashMap
会这样做,所以请改用它。
据记载...... HashMap
:
此课程不保证地图的顺序;特别是,它不保证订单会随着时间的推移保持不变。
Map接口的哈希表和链表实现,具有可预测的迭代顺序。此实现与HashMap的不同之处在于它维护了一个贯穿其所有条目的双向链表。此链接列表定义迭代排序,通常是键插入映射的顺序(插入顺序)。
答案 1 :(得分:5)
使用 LinkedHashMap 代替HashMap来维护秩序。
Map<String,String> map = new LinkedHashMap<String, String>();
答案 2 :(得分:2)
为什么不能更改Map
实施(例如LinkedHashMap
)?
如果存在逻辑排序,您可以使用自定义Comparator
对列表进行排序。
答案 3 :(得分:1)
HashMap
不保留插入顺序
基于哈希表的Map接口实现。此实现提供所有可选的映射操作,并允许空值和空键。 (HashMap类大致相当于Hashtable,除了它是不同步的并且允许空值。)这个类不保证地图的顺序;特别是,它不保证订单会随着时间的推移保持不变。
如果要保留键的顺序,请使用LinkedHashMap
答案 4 :(得分:0)
考虑让您的商品可以排序。在字符串的情况下,已经有了自然的顺序;按字母顺序排列。您可以创建使用可排序类的对象,因此您可以使用排序算法将这些对象放在一个很好的顺序中,无论您从哈希中获取它们的顺序如何!
答案 5 :(得分:0)
现在是LinkedHashMap
的时候了,这意味着要保留广告订单。
请注意,即使存在TreeMap
,也可以使用Comparable接口保留所需的订单。它不再是哈希映射,而是一棵树。
答案 6 :(得分:0)
如果你真的无法切换到另一个Map
实现(LinkedHashMap
正好你想要的那个,那么唯一的另一种可能性就是保留原来的{{1}并使用它从List,
List
Map.
但是我会重构代码,直到可以切换到public <T> List<T> listFromMapInOrder(final Map<T, T> map, final List<T> order) {
List<T> result = new ArrayList<T>();
for (T key : order) {
if (map.containsKey(key)) {
result.add(key);
result.add(map.get(key));
}
}
return result;
}