我有一张 map ,我想根据一些规则对其内容进行排序:
- Sort the map Alphabetically (From A to Z) according to its Values and not its Keys.
- Ignore the Case Sensitivity of the Values while sorting them.
- Put duplicate words into consideration(Words having exact letters Spelling & Case).
- Sort the Alpha numeric words right(Cbc2ee should appear before Cbc100ee).
- Handle non English words(área should appear in the words starting with "a" letter but actually it appears after words starting with "z" letter, considering á another letter).
我认为我想要的都是合乎逻辑的。我能够通过此代码完成第 1、2 和 3 点:
public <K, V extends Comparable<? super V>> LinkedHashMap<K, V> sortMapByValues( Map<K, V> map ) {
SortedSet<Map.Entry<K, V>> sortedEntries = new TreeSet<Map.Entry<K, V>>(
new Comparator<Map.Entry<K, V>>() {
@Override
public int compare( Map.Entry<K, V> e1, Map.Entry<K, V> e2 ) {
String a = (String)e1.getValue();
String b = (String)e2.getValue();
int diff = a.compareToIgnoreCase( b );
if (diff == 0)
diff = a.compareTo(b);
return diff != 0 ? diff : 1; // Special fix to preserve words with similar spelling.
}
}
);
sortedEntries.addAll( map.entrySet() );
LinkedHashMap<K, V> sortedMap = new LinkedHashMap<K, V>();
for( Map.Entry<K, V> sortedEntry : sortedEntries )
sortedMap.put( sortedEntry.getKey(), sortedEntry.getValue() );
return sortedMap;
}
第(4)点我已经找到了它的脚本,但我无法将它与我的代码合并: http://www.davekoelle.com/alphanum.html
第(5)点我也找到了它的脚本,但我无法将它与我的代码合并: http://www.javapractices.com/topic/TopicAction.do?Id=207
因为这些点会影响compare(...)方法。 有人可以帮我吗?
最佳答案
几点...
方法签名应该是:
public static <K, V> Map<K, V> sortMapByValues(Map<K, V> map)
注意:
- 删除对 Comparable
的绑定(bind),因为您正在比较 toString()
map 值,而不是值本身
- 抽象类型规范Map<...>
,而不是具体的LinkedHashMap
,根据良好的设计指南
-static
因为它不会改变状态 - 它“只是代码”
那么,你的解决方案非常好。它只需要更多的代码来实现这些额外的点。
这里有一些代码可以实现您想要的功能:
public static <K, V> Map<K, V> sortMapByValues(Map<K, V> map) {
SortedSet<Map.Entry<K, V>> sortedEntries = new TreeSet<Map.Entry<K, V>>(new Comparator<Map.Entry<K, V>>() {
public int compare(Map.Entry<K, V> e1, Map.Entry<K, V> e2) {
String aRaw = e1.getValue().toString();
String bRaw = e2.getValue().toString();
String a = standardize(aRaw);
String b = standardize(bRaw);
// Check for hex
try
{
Integer ai = Integer.parseInt(a, 16);
Integer bi = Integer.parseInt(b, 16);
int diff = ai.compareTo(bi);
if (diff != 0)
return diff;
}
catch (NumberFormatException ignore)
{
}
int diff = a.compareTo(b);
if (diff != 0)
return diff;
return aRaw.compareTo(bRaw);
}
/** This method removes all accent (diacritic) marks and changes to lower case */
String standardize(String input) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < input.length(); i++) {
char c = input.charAt(i);
sb.append(Normalizer.normalize(c + "", Form.NFD).replaceAll("\\p{InCombiningDiacriticalMarks}+", ""));
}
return sb.toString().toLowerCase();
}
});
// The rest is your code left as it was, cos it's fine
sortedEntries.addAll(map.entrySet());
LinkedHashMap<K, V> sortedMap = new LinkedHashMap<K, V>();
for (Map.Entry<K, V> sortedEntry : sortedEntries)
sortedMap.put(sortedEntry.getKey(), sortedEntry.getValue());
return sortedMap;
}
测试代码如下:
public static void main(String[] args) {
Map<String, String> map = new HashMap<String, String>();
map.put("a", "CC96");
map.put("b", "CC97");
map.put("c", "CC102");
map.put("d", "CC103");
map.put("e", "aabbcc");
map.put("f", "aabbCC");
map.put("g", "atabends");
map.put("h", "aaBBcc");
map.put("i", "AABBcc");
map.put("j", "aabbcc");
map.put("k", "Cc102");
map.put("l", "baldmöglichst");
map.put("m", "bar");
map.put("n", "barfuss");
map.put("o", "barfuß");
map.put("p", "spätabends");
map.put("q", "ätabends");
map.put("r", "azebra");
System.out.println(sortMapByValues(map).toString()
.replaceAll(", ", "\r").replaceAll("(\\{|\\})", ""));
}
输出:
a=CC96
b=CC97
c=CC102
k=Cc102
d=CC103
i=AABBcc
h=aaBBcc
f=aabbCC
e=aabbcc
g=atabends
q=ätabends
r=azebra
l=baldmöglichst
m=bar
n=barfuss
o=barfuß
p=spätabends
关于java - 根据某些规则对 Map 进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8628747/