[英]How to Sort objects by 2 fields Java
The file I am trying to read looks like this:我要读取的文件如下所示:
1995 Pokemon Ikue Ôtani
1940 Tom and Jerry William Hanna
1995 Pokemon voice actor2
1940 Tom and Jerry voice actor3
2000 Cartoon voice actor
It has around 20k rows.它有大约 20k 行。 I already got the reading the file and storing the data in an object.
我已经读取文件并将数据存储在 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 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;
}
};
I would like to read the file in threads and sort by year.我想在线程中读取文件并按年份排序。 Can anyone provide sample code on how can multithread and merge sort be implemented together?
谁能提供有关如何一起实现多线程和合并排序的示例代码?
The output that I'd like to get我想得到的 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
Try this.尝试这个。
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());
}
Sticking with your data structure (just renaming it from the rather peculiar CartoonYear
to Cartoon
), and also sticking with the good approach of using Java streams by @saka1029 (instead of manually implementing a merge sort algorithm), you could do something like this:坚持你的数据结构(只是将它从相当奇特的
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);
}
});
}
}
This was just quick & dirty, not code I am proud of.这只是快速而肮脏的,而不是我引以为豪的代码。 Your requirement to only print year and title once per group does not make the code nicer with the
if-else
either.您要求每组只打印一次年份和标题也不会使
if-else
代码更好。 But assuming you have an input file like this:但是假设你有一个这样的输入文件:
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
you will get output like this:你会得到 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.