如何解决如何按2个字段对对象进行排序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
它大约有2万行。我已经可以读取文件并将数据存储在对象中。
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
对象
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;
}
};
我想在线程中读取文件并按年份排序。谁能提供示例代码说明如何一起实现多线程和合并排序?
我想要获得的输出
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[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
您将获得如下输出:
11 Sample foo
bar
1940 Tom and Jerry William Hanna
voice actor3
1995 Pokemon Ikue Ôtani
voice actor2
2000 Cartoon voice actor
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。