如何对使用Formatter创建的表格进行排序?

huangapple go评论54阅读模式
英文:

How to sort a table created with Formatter?

问题

我创建了一个从文件中读取文本、计算每个单词出现次数并将所有内容放入使用Formatter创建的表格的应用程序。现在我想按单词的出现次数对表格进行排序。以下是迄今为止的代码:

package com.example.antonpaarapplication;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;

public class Application {

    // 初始化应用程序的函数。
    public void run() {
        System.out.println("您想处理整个文件(1)还是仅处理特定行(2)?");
        choice();
    }

    // 选择是一次性处理整个文件还是仅处理选择的特定文件的函数。
    public void choice() {
        Scanner scanner = new Scanner(System.in);
        int number = scanner.nextInt();
        switch (number) {
            case 1:
                System.out.println("\n已输入数字1,正在处理整个文件。\n");
                processWholeFile();
                break;
            case 2:
                System.out.println("\n已输入数字2,请指定要处理的行。\n");
                processSpecificLines();
                break;
            default:
                System.out.println("无效,请重试。");
                choice();
        }
    }

    // 处理整个文件的函数。
    public void processWholeFile() {
        Map<String, Integer> stringMap = new HashMap<>();
        Formatter formatter = new Formatter();
        List<String> lines = readFile();
        String string = String.join(" ", lines);
        String[] arr = string.split(" ");

        for (String s : arr) {
            if (stringMap.containsKey(s)) {
                stringMap.put(s, stringMap.get(s) + 1);
            } else {
                stringMap.put(s, 1);
            }
        }

        formatter.format("%20s %20s\n\n", "单词", "出现次数");
        for (Map.Entry<String, Integer> mapEntry : stringMap.entrySet()) {
            if (mapEntry.getKey().substring(0, 1).equals("1")) {
                formatter.format("%20s %20s\n", mapEntry.getKey(), mapEntry.getValue());
            } else {
                formatter.format("%20s %15s\n", mapEntry.getKey(), mapEntry.getValue());
            }
        }
        System.out.println(formatter);
    }

    // 处理文件特定部分的函数。
    public void processSpecificLines() {

    }

    // 读取"data.txt"的内容。
    public List<String> readFile() {
        List<String> lines = new ArrayList<>();
        try {
            lines = Files.readAllLines(Paths.get(System.getProperty("user.dir"), "src", "main", "resources", "data.txt"));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return lines;
    }

    public static void main(String[] args) {
        Application app = new Application();
        app.run();
    }
}

我尝试在Google上搜索这个问题,但似乎要么不可能实现,要么没有人想过这个问题,因为我找不到相关信息。

英文:

I made an application that reads text from a file, counts each word, and puts everything into a table created with Formatter. Now I would like to sort the table by the number Occurrences per word. Here is my code so far:

java

package com.example.antonpaarapplication;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
public class Application {
//Function for Initializing the Application.
public void run() {
System.out.println(&quot;Would you like to process the entire file(1) or just specific lines(2)?&quot;);
choice();
}
//Function for choosing whether to process the entire file at once or only select specific files to be processed.
public void choice() {
Scanner scanner = new Scanner(System.in);
int number = scanner.nextInt();
switch (number) {
case 1:
System.out.println(&quot;\nNumber 1 has been entered, processing whole file.\n&quot;);
processWholeFile();
break;
case 2:
System.out.println(&quot;\nNumber 2 has been entered, please specify lines to be processed. \n&quot;);
processSpecificLines();
break;
default:
System.out.println(&quot;Invalid, please try again.&quot;);
choice();
}
}
//Function for processing the entire File.
public void processWholeFile() {
Map&lt;String, Integer&gt; stringMap = new HashMap&lt;String, Integer&gt;();
Formatter formatter = new Formatter();
List&lt;String&gt; lines = readFile();
String string = String.join(&quot; &quot;, lines);
String[] arr = string.split(&quot; &quot;);
for (String s : arr) {
if (stringMap.containsKey(s)) {
stringMap.put(s, stringMap.get(s) + 1);
} else {
stringMap.put(s, 1);
}
}
formatter.format(&quot;%20s %20s\n\n&quot;, &quot;Word&quot;, &quot;Occurence&quot;);
for (Map.Entry&lt;String, Integer&gt; mapEntry : stringMap.entrySet()) {
if (mapEntry.getKey().substring(0, 1).equals(&quot;1&quot;)) {
formatter.format(&quot;%20s %20s\n&quot;, mapEntry.getKey(), mapEntry.getValue());
} else {
formatter.format(&quot;%20s %15s\n&quot;, mapEntry.getKey(), mapEntry.getValue());
}
}
System.out.println(formatter);
}
//Function for processing specific parts of the file.
public void processSpecificLines() {
}
//Reads the contents of the &quot;data.txt&quot;.
public List&lt;String&gt; readFile() {
List&lt;String&gt; lines = new ArrayList&lt;&gt;();
try {
lines = Files.readAllLines(Paths.get(System.getProperty(&quot;user.dir&quot;), &quot;src&quot;, &quot;main&quot;, &quot;resources&quot;, &quot;data.txt&quot;));
} catch (IOException e) {
throw new RuntimeException(e);
}
return lines;
}
public static void main(String[] args) {
Application app = new Application();
app.run();
}
}

I tried googling the problem, but it seems like this either not possible or nobody has every thought about it, as I can't find anything about it.

答案1

得分: 1

问题不在于 Formatter 本身,而在于在格式化之前如何存储数据,使用了一个不维护任何顺序的 HashMap。您可以改用一个可排序的集合,例如:

List<Map.Entry<String, Integer>> sortedList = new ArrayList<>(stringMap.entrySet());
sortedList.sort(Map.Entry.<String, Integer>comparingByValue().reversed());

formatter.format("%20s %20s\n\n", "Word", "Occurrence");
for (Map.Entry<String, Integer> mapEntry : sortedList) {
    if (mapEntry.getKey().substring(0, 1).equals("1")) {
        formatter.format("%20s %20s\n", mapEntry.getKey(), mapEntry.getValue());
    } else {
        formatter.format("%20s %15s\n", mapEntry.getKey(), mapEntry.getValue());
    }
}
英文:

The problem is not with the Formatter itself, but how you're storing the data before formatting it, using a HashMap which doesn't maintain any ordering. You could use a sortable collection instead, like:

List&lt;Map.Entry&lt;String, Integer&gt;&gt; sortedList = new ArrayList&lt;&gt;(stringMap.entrySet());
sortedList.sort(Map.Entry.&lt;String, Integer&gt;comparingByValue().reversed());

formatter.format(&quot;%20s %20s\n\n&quot;, &quot;Word&quot;, &quot;Occurrence&quot;);
for (Map.Entry&lt;String, Integer&gt; mapEntry : sortedList) {
    if (mapEntry.getKey().substring(0, 1).equals(&quot;1&quot;)) {
        formatter.format(&quot;%20s %20s\n&quot;, mapEntry.getKey(), mapEntry.getValue());
    } else {
        formatter.format(&quot;%20s %15s\n&quot;, mapEntry.getKey(), mapEntry.getValue());
    }
}

huangapple
  • 本文由 发表于 2023年7月3日 23:17:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/76606078.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定