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

时间:2015-04-06 03:04:07

标签: java sorting arraylist

这是一个棘手而长期的问题,所以请耐心等待。

我在表单的输入文件中有有限数量的行:

2015000,Advanced YouTube Commenting,Department of Comp Sci,3

2015001,Basket Weaving,Department of Fine Arts,1,等等......

main方法设置构造函数:

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

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

号码"1"告诉我是否 我想按照crns(由0表示),他们的names(1),他们的departments(2)或他们的year(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

2 个答案:

答案 0 :(得分:1)

更好的方法(特别是考虑到您使用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;
  }
}

然后,您可以在读取数据时简单地将每行转换为数据,对数据的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以便于实现。

答案 1 :(得分:0)

尝试TreeMap

TreeMap<String, String> treemap = new TreeMap<>();

private void insertSortedOn(String line, int fieldIndex){
    String[] tokens = line.trim().split(",");
    treemap.put(tokens[fieldIndex], line);
}

实际上,您可以为每个“元素”保留不同的TreeMap。它根据您用作密钥的任何内容进行排序。由于您的元素始终为4,因此每个键可以使用4 TreeMap个正确的类型。因为他们只持有引用,所以不会有太多的内存重复。