我有一个读取.txt文件的程序,创建一个包含每个唯一字符串及其出现次数的HashMap,我想创建一个ArrayList,根据它们的出现次数按降序显示这些唯一字符串。
目前,我的程序按字母顺序从降序排序(使用我假设的ASCII值)。
我如何根据其出现次数按降序排序?
以下是代码的相关部分:
Scanner in = new Scanner(new File("C:/Users/ahz9187/Desktop/counter.txt"));
while(in.hasNext()){
String string = in.next();
//makes sure unique strings are not repeated - adds a new unit if new, updates the count if repeated
if(map.containsKey(string)){
Integer count = (Integer)map.get(string);
map.put(string, new Integer(count.intValue()+1));
} else{
map.put(string, new Integer(1));
}
}
System.out.println(map);
//places units of map into an arrayList which is then sorted
//Using ArrayList because length does not need to be designated - can take in the units of HashMap 'map' regardless of length
ArrayList arraylist = new ArrayList(map.keySet());
Collections.sort(arraylist); //this method sorts in ascending order
//Outputs the list in reverse alphabetical (or descending) order, case sensitive
for(int i = arraylist.size()-1; i >= 0; i--){
String key = (String)arraylist.get(i);
Integer count = (Integer)map.get(key);
System.out.println(key + " --> " + count);
}
答案 0 :(得分:1)
在Java 8中:
public static void main(final String[] args) throws IOException {
final Path path = Paths.get("C:", "Users", "ahz9187", "Desktop", "counter.txt");
try (final Stream<String> lines = Files.lines(path)) {
final Map<String, Integer> count = lines.
collect(HashMap::new, (m, v) -> m.merge(v, 1, Integer::sum), Map::putAll);
final List<String> ordered = count.entrySet().stream().
sorted((l, r) -> Integer.compare(l.getValue(), r.getValue())).
map(Entry::getKey).
collect(Collectors.toList());
ordered.forEach(System.out::println);
}
}
首先使用Files.lines
方法读取文件,该方法会为您提供Stream<String>
行。
现在使用Map<String, Integer>
方法将行收集到Map.merge
中,该方法接受键和值以及应用于旧值的lambda和新值(如果键已存在)
你现在有了你的计数。
现在获取Stream
的{{1}} entrySet
,然后按Map
的{{1}}对其进行排序,然后选择value
}。将其收集到Entry
。您现在有key
个值按计数排序。
现在只需使用List
打印它们。
如果仍在使用Java 7,您可以使用List
提供排序顺序:
forEach
答案 1 :(得分:0)
您尚未显示地图的声明,但出于此答案的目的,我假设您的地图声明如下:
Map<String,Integer> map = new HashMap<String,Integer>();
您需要在调用中使用Comparator
进行排序,但需要按计数进行比较,同时记住字符串。因此,您需要在列表中放置具有字符串和计数的对象。
提供此功能且可以从Map.entrySet
方法轻松获得的一种类型是Map.Entry
类型。
最后一部分使用Map.Entry
和Comparator
重写:
ArrayList<Map.Entry<String,Integer>> arraylist = new ArrayList<Map.Entry<String,Integer>>(map.entrySet());
Collections.sort(arraylist, new Comparator<Map.Entry<String,Integer>>() {
@Override
public int compare(Entry<String, Integer> e1, Entry<String, Integer> e2) {
// Compares by count in descending order
return e2.getValue() - e1.getValue();
}
});
// Outputs the list in reverse alphabetical (or descending) order, case sensitive
for (Map.Entry<String,Integer> entry : arraylist) {
System.out.println(entry.getKey() + " --> " + entry.getValue());
}