问题
I am looking at a redundant list of Strings, e.g.
{ "One", "One", "One", "Two", "Three", "Three" }
What is the best way to count the occurrences, then create a non-redundant list of the strings, sorted by the number of occurrences?
The result I want is a List like this:
{ "One", "Three", "Two" }
回答1:
You can use the trick in the most voted answer of this question about how to sort the map by its values.
Here is an example implementation (I have added generics to the comparator):
- you add the strings / occurences to a hashmap
- put everything in a TreeMap with a custom comparator that sorts on the values
- put the keys back in a list
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));
}
}
回答2:
It can be done quickly in 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);
Output here :-
{One=3, Three=2, Two=1}
OR
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));
Output:-
{Two=1, Five=2, Three=2, One=3}
回答3:
You could create a Map, go through your list, everytime you come across a new occurance put it into the list and set the integer value to 1, everytime you come across a duplicate just increase the value by one for that particular key.
Then go through and create your sorted list from the counts in the hashmap.
Or as others have suggested using a TreeMap will allow you to sort rather than creatign sepearet list.
来源:https://stackoverflow.com/questions/11504902/simple-way-to-count-occurrences-of-string-and-sort-by-them