外側のマップが自然な順序である場合はTreeMap<String, TreeMap<Character, Integer>>
を使用し、内側のマップは文字の出現回数と最初の位置に従ってソートされます(これは例の出力に一致します)。
は
コードは次のようになります。
private static TreeMap<String, Map<Character, Integer>> tokenize(String[] words) {
TreeMap<String, Map<Character, Integer>> map = new TreeMap<>();
for (String word : words) {
Map<Character, Integer> counterMap = new LinkedHashMap<>();
Map<Character, Integer> positionMap = new LinkedHashMap<>();
for (int i = 0; i < word.length(); ++i) {
char ch = word.charAt(i);
int current = counterMap.getOrDefault(ch, 0);
counterMap.put(ch, current + 1);
positionMap.putIfAbsent(ch, i);
}
TreeMap<Character, Integer> sortedCounterMap = new TreeMap<>((ch1, ch2) -> {
int counterCmp = counterMap.get(ch2) - counterMap.get(ch1);
if (counterCmp != 0) return counterCmp;
return positionMap.get(ch1) - positionMap.get(ch2);
});
sortedCounterMap.putAll(counterMap);
map.put(word, sortedCounterMap);
}
return map;
}
同じ出現回数と文字の順序が指定されていない場合、内部の並べ替えは少し考え方は同じですが、単純化することができます。
private static TreeMap<String, Map<Character, Integer>> tokenize(String[] words) {
TreeMap<String, Map<Character, Integer>> map = new TreeMap<>();
for (String word : words) {
Map<Character, Integer> counterMap = new LinkedHashMap<>();
for (int i = 0; i < word.length(); ++i) {
char ch = word.charAt(i);
int current = counterMap.getOrDefault(ch, 0);
counterMap.put(ch, current + 1);
}
TreeMap<Character, Integer> sortedCounterMap = new TreeMap<>((ch1, ch2) -> {
int counterCmp = counterMap.get(ch2) - counterMap.get(ch1);
if (counterCmp != 0) return counterCmp;
return ch1 - ch2;
});
sortedCounterMap.putAll(counterMap);
map.put(word, sortedCounterMap);
}
return map;
}
ソート順に整理しなければならない特別な理由はありますか?定期的な辞書を使って、印刷する必要があるときに並べ替えることができますか? –
hello = l:2、h:1、e:1、o:1、hの前にどうなるか –
'TreeMap>'をインナー'Entry :: getValue'でソートされたエントリセットから作成されたマップです。 –
shmosel