【问题标题】:Java - text to array to textJava - 文本到数组到文本
【发布时间】:2017-01-17 19:15:43
【问题描述】:

我正在寻找从一个小文本文件中读取整数+字符串的最佳方法,将它们保存在一个数组中,添加一些新的整数+字符串,按整数对它们进行排序,然后在同一个文件中写入最高的几个。 (比如高分)

示例:

sth.txt

5 aa
4 bb
3 cc
3 dd

进入

a["5 aa","4 bb","3 cc","3 dd"] 

添加一些新字符串

a["5 aa","4 bb","3 cc","3 dd","1 aa","7 bb"]

排序后写回sth.txt

7 bb
5 aa
4 bb
3 cc

如何在 Java 中做到这一点?

【问题讨论】:

  • 试试 Java Map,它允许您将字符串与分数相关联。
  • 关于如何在Java中读取文本文件,如何将数据存储在数组(或列表)中,如何对数组/列表进行排序,如何将文本写入文件,有很多问题。你在哪一步有问题?向我们展示您的代码并描述您面临的具体问题。
  • 使用类来解析测试文件并使用该类的列表,然后使用 Collections.sort 和自定义比较器!你能做到吗?
  • @RAZ_Muh_Taz 抱歉,应该从那开始。我首先尝试读/写不同的文件,然后找到了 10 种不同的方法,然后在某个地方迷路了。我最近的也是我认为最成功的尝试:pastebin.com/m424enLC

标签: java string sorting io integer


【解决方案1】:

您可以按如下操作,代码中包含一个 cmets 以便更好地理解。

public static void main(String[] args) throws IOException {
    Data[] map = new Data[6];
    //Then read the data from your file , in my case
    //i will make a dummy data.
    map[0] = new Data(5, "aa");
    map[1] = new Data(4, "bb");
    map[2] = new Data(3, "cc");
    map[3] = new Data(3, "dd");
    map[4] = new Data(1, "aa");
    map[5] = new Data(7, "bb");
    //Then sorting this array
    java.util.Arrays.sort(map);
    //Then print the highet 4 records
    for (int i = 0; i < 4; i++) {
        System.out.println(map[i].FirstPart + " " + map[i].SecondPart);
    }
}

假设记录的第一部分是int 类型,第二部分是String,则创建一个适合您需要的类

class Data implements Comparable<Data> {

    int FirstPart;
    String SecondPart;

    public Data(int FirstPart, String SecondPart) {
        this.FirstPart = FirstPart;
        this.SecondPart = SecondPart;
    }
//compareTo method will be called whenever you call a sort method like
// "java.util.Arrays.sort(map);" in the main method

    @Override
    public int compareTo(Data o) {
        if (this.FirstPart < o.FirstPart) {
            return 1;
        } else {
            return -1;
        }
    }
}

输出:

7 bb
5 aa
4 bb
3 dd

【讨论】:

  • 如果两个对象的FirstPart 相等怎么办?我们应该交换这些元素吗?无论如何,您不需要手动编写条件。让Integer.compare 为您完成并简单地返回结果。
  • 如果两个对象有相等的FirstPart,那么他可以做first occur &gt;&gt; first show,反之亦然。甚至他也可以根据SecondPart 进行排序。这都是关于需要@Pshemo 的OP
  • 是的,看起来也不错,我会尝试修复错误并回答。 @Pshemo 我不准确,但没关系。
  • 我担心显示的比较不遵守排序规则。通常如果A&gt;B 表示B&lt;A。所以预计sgn(A.compareTo(B)) = -sgn(B.compareTo(A))。但是,如果 A 和 B 被视为相等(如 map[2]map[3]),则在您的情况下这将失败,因为无论您是比较 (A,B) 还是 (B,A),您都将始终得到 -1。这可能会导致IllegalArgumentException: Comparison method violates its general contract!。目前算法可以允许这个错误,但这并不意味着它会一直这样。
【解决方案2】:

检查以下解决方案--

abc.txt
4 test1
6 test2
0 test3
12 test4
5 test5
9 test6

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;


public class ReadWriteDataInFile {

    public static void main(String[] args) throws IOException {
        String path="C:\\test\\";
        String fileName=path+"abc.txt";
        String newFileName=path+"abcNew.txt";

        System.out.println("Reading Data from File "+fileName + " started...");
        Map<Integer, String> readDataFromTextFile = readDataFromTextFile(fileName);

        System.out.println("Writing Sorted Data to File "+newFileName + " started...");
        writeDataInNewFile(readDataFromTextFile,newFileName);
        System.out.println("Writing Data to File Completed...");
    }


    private static void writeDataInNewFile(Map<Integer, String> readDataFromTextFile, String newFileName) throws IOException {

        PrintWriter writer = new PrintWriter(newFileName, "UTF-8");

        Iterator it = readDataFromTextFile.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry pair = (Map.Entry)it.next();
            String data1=pair.getKey() + " " + pair.getValue();
            writer.println(data1);
        }
        writer.close();
    }

    private static Map<Integer, String> readDataFromTextFile(String fileName) throws IOException {

        FileInputStream fis = new FileInputStream(fileName);
        InputStreamReader input = new InputStreamReader(fis);
        BufferedReader br = new BufferedReader(input);

        String data;
        String result[] ;

        Map<Integer,String> dataMap= new TreeMap<Integer,String> ();
        while ((data = br.readLine()) != null) {
            result = data.split(" ");
            dataMap.put(Integer.parseInt(result[0]), result[1]);
        }
        return dataMap;
    }
}

newabc.txt
0 test3
4 test1
5 test5
6 test2
9 test6
12 test4

【讨论】:

  • 这个对我有用。我会尝试在读取和写入之间添加一些新字符串,然后将“newabc.txt”复制到“abc.txt”中并告诉它是如何工作的。
  • 当然,也发布你的结果。
【解决方案3】:

这里是示例解决方案,包括读取和写入文件:

public class Main {
    static class Entry<T, U> {
        public T value1;
        public U value2;

        public Entry(T value1, U value2) {
            this.value1 = value1;
            this.value2 = value2;
        }
    }

    static Entry<Integer, String> parseLine(String line) {
        String[] intAndString = line.split(" ");
        Integer i = Integer.parseInt(intAndString[0]);
        String s = intAndString[1];
        return new Entry<>(i, s);
    }

    public static void main(String[] args) throws IOException {
        Path path = Paths.get("spl.txt");
        List<Entry<Integer, String>> resultList = new LinkedList<>();
        try (BufferedReader reader = Files.newBufferedReader(path)) {
            String nextLine;
            while ((nextLine = reader.readLine()) != null) {
                if (nextLine.equals("\n") || nextLine.isEmpty()) continue;
                resultList.add(parseLine(nextLine));
            }
        }
        Collections.sort(resultList, (e1, e2) -> e1.value1 - e2.value1 != 0 ? e1.value1 - e2.value1 : e1.value2.compareTo(e2.value2));
        try (BufferedWriter writer = Files.newBufferedWriter(path)) {
            resultList.forEach((e) -> {
                try {
                    writer.write(e.value1 + " " + e.value2 + "\n");
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            });
        }
    }
}

由于可读性而省略了类条目的封装。
升序顺序排序。
希望它会有所帮助。

【讨论】:

  • 是的,这几乎正是我想要的。问题是,它们写在一行中,没有可见的分隔符(比如“\n”不起作用),所以我用 [enter] 将它们分隔并保存并重新运行应用程序,但我遇到了一个令人讨厌的异常:pastebin.com/5TT6HqxC。我不明白为什么,因为它们最初是用 [enter] 分隔的。
  • 问题出在文件末尾的换行符中,请查看我的新解决方案。
  • 不知何故它对我来说仍然有效 - 在一行中返回字符串并以新行结束,就像 "\n" 只在最后工作,而且似乎在某处添加了空字符,因为每当我在它们之间输入并在末尾删除新的行号时(选中 - 我是否删除它都没有关系),我会得到上面提到的异常。
  • 好的,我改了。但请记住,它适用于您给出的格式:数字字符串和新行,例如:“5 aa”
  • 是的,文件总是读得很好,但结果总是像 C 的所有行的 strcpy,比如“1 aa2 aa3 aa”+末尾的新行。在我用 [enter] 分隔行后,在末尾删除新行,保存文件,关闭它并重新运行,它总是抛出该异常。在我从文本文件中删除整个文本并手动重新键入后,它不会引发异常,但结果是相同的。那个也查了,还是一样。我不知道为什么,但就我对 Java 的理解而言,您的代码对我来说似乎是合法的。
猜你喜欢
  • 2014-07-29
  • 1970-01-01
  • 2018-04-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多