我有一个Map排序如下:
Map<String, String> map = new HashMap();
它包含以下字符串键:
String key = "key1.key2.key3.key4"
它包含以下字符串值:
String value = "value1.value2"
其中的键和值可能会因点数从 key1 / value1 到 key1.key2.key3.key4.key5而有所不同/value1.value2.value3.value4.value5 非同质
我需要根据键中存在的点数或根据调用方法类型键 / 值的值来比较它们:
sortMap(Map map, int byKey);
或
sortMap(Map map, int byValue);
当然,这些方法会返回一个有序的地图。
任何帮助都将不胜感激。
答案 0 :(得分:4)
无法在HashMap
上强加任何排序。
如果您想通过键上的某些比较对元素进行排序,请在键上使用TreeMap
一些Comparator
,或者只使用默认的Comparable
排序。
如果您想按值排序,唯一真正的选择是使用LinkedHashMap
,它保留条目放入地图的顺序,然后在将条目插入地图之前对条目进行排序,或者可能是一些非JDK Map
实现。有一些肮脏的黑客使得一个关键的比较器实际上秘密地比较了这些值,但这些很危险并经常导致不可预测的行为。
答案 1 :(得分:1)
对于初学者,您需要使用SortedMap
的实例。如果映射没有实现该接口,那么它具有未定义/任意迭代顺序,您无法控制它。 (通常情况就是这样,因为地图是一种将值与键相关联的方式;排序是一个辅助问题。)
所以我假设你正在使用TreeMap,这是规范的有序地图实现。这会根据您在构造函数中提供的Comparator对其键进行排序。因此,如果您可以编写这样的比较器来确定哪个是两个任意键的“较低”(扰码警报:您可以),这将很容易实现。
但是,这仅在按键排序时有效。我不知道按值排序地图是否有意义,我不知道有任何直接的方法来做到这一点。我能想到的最好的是编写一个对值进行排序的Comparator<Map.Entry>
,调用Map.getEntrySet
并将所有条目推送到列表中,然后在列表中调用Collections.sort
。它不是非常优雅或高效,但如果性能不是您的主要考虑因素,它应该完成工作。
(另请注意,如果您的密钥不是不可变的,您将遇到很多麻烦,因为外部更改时不会使用它们。
答案 2 :(得分:1)
您应该使用TreeMap并实现ValueComparator或创建实现Comparable的键和值对象。
这里必须重复......
编辑:重复(仅命名一个)Sort a Map<Key, Value> by values (Java)
答案 3 :(得分:0)
我是通过以下方式做到的:
@SuppressWarnings({ "unchecked", "rawtypes" })
public static Map sortMap(Map unsortedMap) {
List list = new LinkedList(unsortedMap.entrySet());
// sort list based on comparator
Collections.sort(list, new Comparator() {
public int compare(Object o1, Object o2) {
String value1 = (String)((Map.Entry) (o1)).getValue();
String value2 = (String)((Map.Entry) (o2)).getValue();
// declare the count
int count1 = findOccurances(value1, '.');
int count2 = findOccurances(value2, '.');
// Go to thru the comparing
if(count1 > count2){
return -1;
}
if(count1 < count2){
return 1;
}
return 0;
}
});
// put the sorted list into map again
Map sortedMap = new LinkedHashMap();
for (Iterator it = list.iterator(); it.hasNext();) {
Map.Entry entry = (Map.Entry) it.next();
sortedMap.put(entry.getKey(), entry.getValue());
}
return sortedMap;
}
使用以下辅助方法:
private static int findOccurances(String s, char chr) {
final char[] chars = s.toCharArray();
int count = 0;
for (int i = 0; i < chars.length; i++) {
if (chars[i] == chr) {
count++;
}
}
return count;
}
在这里,我可以在比较部分添加一些switch
,并在 asc / desc 之间更改int
参数。
我可以通过另一个switch
参数值的int
来更改值和键,以获得我的答案。