java - 按行内的元素对 ArrayList 中的行进行排序

标签 java sorting arraylist

这是一个有点棘手且冗长的问题,所以请耐心等待。

我的输入文件中的行数有限:

2015000,高级 YouTube 评论,计算机科学系,3

2015001,编篮,美术系,1,等...

main方法设置构造函数:

FileUtil fUtil1 = new FileUtil("input.txt",1,"output1.txt");

"input.txt" 是从中获取这些行的文件,"ouput1.txt" 是将写入这些行的文件。

数字“1”告诉我是否 我想按照它们的 crns (用 0 表示)、它们的 names (1)、它们的 departments (2) 来排列这些行,或者他们的年份 (3)。

所以困难的部分是,我不仅必须按升序排列这些行,而且还必须按升序排列它们的ELEMENTS

我的问题是;有没有比我目前的方法更有效的方法?我们还没有学习如何标记ArrayLists,但也许这是一个更好的方法。

这是我到目前为止所拥有的:

private ArrayList<String> memFile; // sorted lines from input file
private int column;
....
public void sort(){

  BufferedReader inFile;
  String readLine;
  // I read in each line of the text file and add it to the `ArrayList<String> memFile`
  try{
    inFile = new BufferedReader(new FileReader(inputFile));
    while((readLine = inFile.readLine()) != null){
    memFile.add(readLine);
    insertSorted(readLine);

    }//while
    inFile.close();
  }//try

  catch(IOException e){
    System.out.println(e.getMessage());
  }//catch
}//sort

private void insertSorted(String line){

  // I tokenize the given line to get each element
  String[] tokens = line.trim().split(",");
  int registration = Integer.parseInt(tokens[0]); //crn number
  String title = tokens[1]; // course name
  String department = tokens[2]; // course department 
  int year = Integer.parseInt(tokens[3]); // course year
  String word = "";  

  //I look at the lines already in the list, and then tokenize them
  int index = memFile.size() - 1;
  String otherLine = memFile.get(index);
  String[] tokens2 = otherLine.trim().split(",");
  int registration2 = Integer.parseInt(tokens2[0]); //crn number
  String title2 = tokens2[1]; // course name
  String department2 = tokens2[2]; // course department 
  int year2 = Integer.parseInt(tokens2[3]); // course year
  String otherWord = "";

  // if the given column equals the token position in the line, then make a new word
  for(int i = 0; i < tokens.length; i++){
    if(column == i){
      word = (String)tokens[i];
      otherWord = (String)tokens2[i];}
    else{
      word = null;}
  }
  //sort the list
  while(index >= 0 && (otherWord).compareTo(word) > 0)
    index--;
    memFile.add(index+1,line);
}//insertSorted

最佳答案

更好的方法(特别是考虑到您使用的是 Java)是创建一个类来表示数据,而不是尝试自始至终都使用字符串。考虑一下这个类:

public class Data{
  public final int crns;
  public final String name;
  public final String department;
  public final int year;

  public Data(int crns, String name, String department, int year){
    this.crns = crns;
    this.name = name;
    this.department = department;
    this.year = year;
  }

  public String toString(){
    return crns + "," + name + "," + department + "," + year;
  }
}

然后,您可以在读入时将每一行简单地转换为 Data,对 Data 的 ArrayList 执行操作,然后将它们转换回字符串。

private ArrayList<Data> memFile;
private int column;
....
public void sort(){

  memFile.clear(); //Make sure that calling sort twice doesn't break it
  BufferedReader inFile;
  String readLine;
  try{
    inFile = new BufferedReader(new FileReader(inputFile));
    while((readLine = inFile.readLine()) != null){

      try{
        //Read and split the next line
        String[] tokens = readLine.trim().split(",");
        int registration = Integer.parseInt(tokens[0]); //crn number
        String title = tokens[1]; // course name
        String department = tokens[2]; // course department 
        int year = Integer.parseInt(tokens[3]); // course year

        //Convert to a data instance and add to the arrayList
        memFile.add(new Data(registration, title, department, year));
      }catch(NumberFormatException e){
        System.err.println("Found badly formatted line: " + readLine);
      }
    }
    inFile.close();

    //Sort according to the correct field 
    Collections.sort(memFile, new Comparator<Data>(){
      public int compare(Data d1, Data d2){
        switch(column){
          case 0: return d1.crns - d2.crns;
          case 1: return d1.name.compareTo(d2.name);
          case 2: return d1.department.compareTo(d2.department);
          case 3: return d1.year - d2.year;
          default: return 0;
        }
      }
    });
  }
  catch(IOException e){
    System.out.println(e.getMessage());
  }
}

如果您这样做是为了学习,那么您应该通过改进 Data 类来对此进行扩展。如:

  • 添加一个构造函数 public Data(String line),用于在内部解析字段,并在需要时抛出异常。然后你可以将读取的行传递到构造函数中
  • 添加适用于 Data 类的 equals 和 hashcode 方法。提示 - 使用 Objects.equals 和 Objects.hashcode 可以轻松实现。

关于java - 按行内的元素对 ArrayList 中的行进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29464775/

相关文章:

function - jQuery 函数在 Safari 上不起作用

java - 数组列表过滤器

java - 无法解析的日期异常java日期模式

java - 使用 Java Media Framework 在 Java 中播放 WAV 文件

java - itextpdf 特定页面上的不同边距

Python 3.x 对列表中包含数字和字母的文件名进行排序

java - KeyListener 不工作,即使它看起来是正确的

python - 使用多个条件对列表列表进行排序 (Python)

java - 从数组中提取信息

java - 创建一个类来存储在 ArrayList 中创建的所有对象?