Java 如何从.txt文件中读取字符串,并根据出现的次数将其排序到ArrayList中?

Java 如何从.txt文件中读取字符串,并根据出现的次数将其排序到ArrayList中?,java,sorting,arraylist,hashmap,counter,Java,Sorting,Arraylist,Hashmap,Counter,我有一个程序可以读取一个.txt文件,创建一个包含每个唯一字符串及其出现次数的HashMap,我想创建一个ArrayList,以降序显示这些唯一字符串的出现次数 目前,我的程序从字母顺序的角度按降序排序(我假设使用ASCII值) 我如何根据它们的出现次数按降序排列 以下是代码的相关部分: Scanner in = new Scanner(new File("C:/Users/ahz9187/Desktop/counter.txt")); while

我有一个程序可以读取一个.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);
            }

您尚未显示地图的声明,但为了回答此问题,我假设您的地图声明如下:

Map<String,Integer> map = new HashMap<String,Integer>();
在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);
    }
}

使用自定义的
比较器
。从
HashMap
中获取出现次数并进行比较…并使用entrySet()而不是keySet(),这样您就拥有了唯一的字符串和出现次数。使用
比较器将完成的HashMap中的所有项目推到一个列表中,就像Boris所说的那样。您需要的是一个最大堆,这样,一旦您将所有内容放入priqueue(按出现次数排序),您就可以
poll()
,直到提取所有元素。旁注:
Integer
支持
+
运算符:
map.put(string,map.get(string)+1)@Boristespider你为什么不回答而不是评论?@sp00m,如果你坚持的话。这太完美了。非常感谢。
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);
    }
}
final Map<String, Integer> counts = /*from somewhere*/
final List<String> sorted = new ArrayList<>(counts.keySet());
Collections.sort(sorted, new Comparator<String>() {

    @Override
    public int compare(final String o1, final String o2) {
        return counts.get(o1).compareTo(counts.get(o2));
    }
});