簡體   English   中英

如何按 2 個字段對對象進行排序 Java

[英]How to Sort objects by 2 fields Java

我要讀取的文件如下所示:

1995     Pokemon    Ikue Ôtani  
1940     Tom and Jerry    William Hanna 
1995     Pokemon    voice actor2
1940     Tom and Jerry    voice actor3
2000     Cartoon      voice actor

它有大約 20k 行。 我已經讀取文件並將數據存儲在 object 中。

        in = new BufferedReader(new FileReader(cartoonsFile));
            
        ArrayList<String> voiceActors = new ArrayList<>();  
        ArrayList<Cartoon> cartoons = new ArrayList<>();    
        
        //read each line
        String line = in.readLine();
        while (line != null) {
            String[] columns = line.split("\\t");
            String year = columns[0];
            String cartoon = columns[1];
            String voiceActor = columns[2];

            //make new object and store data

            Cartoon c = new Cartoon(Integer.parseInt(columns[0]),
                                    columns[1], columns[2]));
            cartoons.add(c); //add to the array list

Object

public class Cartoon {
  private int year;
  private String title;
  private String voiceActor;

  public Cartoon(int year, String title, String voiceActor) {
    this.year = year;
    this.title = title;
    this.voiceActor = voiceActor;
  }
};

我想在線程中讀取文件並按年份排序。 誰能提供有關如何一起實現多線程和合並排序的示例代碼?

我想得到的 output

1940     Tom and Jerry         William Hanna 
                               voice actor2
                               voice actor3
                               voice actor4
                               voice actor5

1995     Pokemon               Ikue Ôtani  
                               voice actor2

         A Cartoon             voice actor1
                               voice actor2
                               voice actor3

2000     Cartoon               voice actor

嘗試這個。

List<CartoonYear> readAndSortByYear(String inFile) throws IOException {
    return Files.readAllLines(Paths.get(inFile))
        .parallelStream()
        .map(line -> line.split("\\t"))
        .map(columns -> new CartoonYear(Integer.parseInt(columns[0]), columns[1], columns[2]))
        .sorted(Comparator.comparing(CartoonYear::getYear))
        .collect(Collectors.toList());
}

堅持你的數據結構(只是將它從相當奇特的CartoonYear重命名為Cartoon ),並堅持使用 @saka1029 的 Java 流的好方法(而不是手動實現合並排序算法),你可以這樣做:

package org.acme;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class Cartoon {
  private int year;
  private String title;
  private String voiceActor;

  public Cartoon(int year, String title, String voiceActor) {
    this.year = year;
    this.title = title;
    this.voiceActor = voiceActor;
  }

  public static Map<String, List<Cartoon>> readAndGroupByYearAndTitle(String inFile) throws IOException {
    return Files.readAllLines(Paths.get(inFile))
      .parallelStream()
      .map(line -> line.split("\\t"))
      .map(columns -> new Cartoon(Integer.parseInt(columns[0]), columns[1], columns[2]))
      .collect(Collectors.groupingBy(cartoon -> String.format("%4d %s", cartoon.year, cartoon.title)));
  }

  public static void main(String[] args) throws IOException {
    Map<String, List<Cartoon>> cartoonsGrouped = readAndGroupByYearAndTitle(args[0]);
    cartoonsGrouped.keySet()
      .parallelStream()
      .sorted()
      .forEachOrdered(group -> {
        boolean firstElement = true;
        for (Cartoon cartoonYear : cartoonsGrouped.get(group)) {
          if (firstElement) {
            System.out.printf("%4d  %-25s  %s%n", cartoonYear.year, cartoonYear.title, cartoonYear.voiceActor);
            firstElement = false;
          }
          else
            System.out.printf("%4s  %-25s  %s%n", "", "", cartoonYear.voiceActor);
        }
      });
  }
}

這只是快速而骯臟的,而不是我引以為豪的代碼。 您要求每組只打印一次年份和標題也不會使if-else代碼更好。 但是假設你有一個這樣的輸入文件:

1995    Pokemon Ikue Ôtani
1940    Tom and Jerry   William Hanna
11  Sample  foo
1995    Pokemon voice actor2
1940    Tom and Jerry   voice actor3
2000    Cartoon voice actor
11  Sample  bar

你會得到 output 像這樣:

  11  Sample                     foo
                                 bar
1940  Tom and Jerry              William Hanna
                                 voice actor3
1995  Pokemon                    Ikue Ôtani
                                 voice actor2
2000  Cartoon                    voice actor

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM