たとえば、文字列の冗長リストを見ています
{ "One", "One", "One", "Two", "Three", "Three" }
出現回数をカウントし、出現回数でソートされた文字列の冗長でないリストを作成する最良の方法は何ですか?
私が望む結果は、次のようなリストです。
{ "One", "Three", "Two" }
値でマップをソートする方法について、この質問の最も投票された回答でトリックを使用できます。
実装例を次に示します (コンパレーターにジェネリックを追加しました)。
public static void main(String[] args) {
String[] strings = {"One", "One", "One", "Two", "Three", "Three"};
//Count occurences
Map<String, Integer> map = new HashMap<String, Integer>();
for (String s : strings) {
if (map.containsKey(s)) {
map.put(s, map.get(s) + 1);
} else {
map.put(s, 1);
}
}
ValueComparator<String, Integer> comparator = new ValueComparator<String, Integer> (map);
Map<String, Integer> sortedMap = new TreeMap<String, Integer> (comparator);
sortedMap.putAll(map);
List<String> sortedList = new ArrayList<String> (sortedMap.keySet());
System.out.println(sortedMap);
System.out.println(sortedList);
}
static class ValueComparator<K, V extends Comparable<V>> implements Comparator<K> {
Map<K, V> map;
public ValueComparator(Map<K, V> base) {
this.map = base;
}
@Override
public int compare(K o1, K o2) {
return map.get(o2).compareTo(map.get(o1));
}
}
Java 8ですばやく実行できます。
Map<String, Long> sortedByCountSet = Stream.of("One", "One", "One", "Two", "Three", "Three")
.collect(Collectors.groupingBy(str->str,TreeMap::new,Collectors.counting()));
System.out.println(sortedByCountSet);
ここに出力:-
{1=3、3=2、2=1}
また
Map<String, Long> sortedByCountSet = Stream.of("One", "One", "One", "Two", "Three", "Three","Five","Five")
.collect(Collectors.groupingBy(str->str, Collectors.counting()))
.entrySet().stream().sorted(Comparator.comparing(Map.Entry::getValue))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,(e1, e2) -> e1,LinkedHashMap::new));
出力:-
{2=1、5=2、3=2、1=3}
マップを作成し、リストを調べて、新しい出現に遭遇するたびにそれをリストに入れ、整数値を 1 に設定し、重複に遭遇するたびに、その特定のキーの値を 1 ずつ増やします。
次に、ハッシュマップのカウントから並べ替えられたリストを作成します。
または、他の人が示唆しているように、TreeMap を使用すると、別のリストを作成するのではなく、並べ替えることができます。