我有两个文件,每个文件具有大约100,000行的相同格式。对于文件一中的每一行,我正在提取第二个组件或列,如果我在第二个文件的第二列中找到匹配,我提取它们的第三个组件并将它们组合,存储或输出它。
虽然我的实现工作但程序运行速度非常慢,但是迭代文件需要一个多小时,比较并输出所有结果。
我正在读取并将这两个文件的数据存储在ArrayList中,然后迭代这些列表并进行比较。下面是我的代码,是否存在任何与性能相关的故障或其正常情况。
注意:我正在使用String.split(),但我理解其他帖子,StringTokenizer更快。
public ArrayList<String> match(String file1, String file2) throws IOException{
ArrayList<String> finalOut = new ArrayList<>();
try {
ArrayList<String> data = readGenreDataIntoMemory(file1);
ArrayList<String> data1 = readGenreDataIntoMemory(file2);
StringTokenizer st = null;
for(String line : data){
HashSet<String> genres = new HashSet<>();
boolean sameMovie = false;
String movie2 = "";
st = new StringTokenizer(line, "|");
//String line[] = fline.split("\\|");
String ratingInfo = st.nextToken();
String movie1 = st.nextToken();
String genreInfo = st.nextToken();
if(!genreInfo.equals("null")){
for(String s : genreInfo.split(",")){
genres.add(s);
}
}
StringTokenizer st1 = null;
for(String line1 : data1){
st1 = new StringTokenizer(line1, "|");
st1.nextToken();
movie2 = st1.nextToken();
String genreInfo2= st1.nextToken();
//If the movie name are similar then they should have the same genre
//Update their genres to be the same
if(!genreInfo2.equals("null") && movie1.equals(movie2)){
for(String s : genreInfo2.split(",")){
genres.add(s);
}
sameMovie = true;
break;
}
}
if(sameMovie){
finalOut.add(ratingInfo+""+movieName+""+genres.toString()+"\n");
}else if(sameMovie == false){
finalOut.add(line);
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return finalOut;
}
答案 0 :(得分:1)
我会使用Streams API
String file1 = "files1.txt";
String file2 = "files2.txt";
// get all the lines by movie name for each file.
Map<String, List<String[]>> map = Stream.of(Files.lines(Paths.get(file1)),
Files.lines(Paths.get(file2)))
.flatMap(p -> p)
.parallel()
.map(s -> s.split("[|]", 3))
.collect(Collectors.groupingByConcurrent(sa -> sa[1], Collectors.toList()));
// merge all the genres for each movie.
map.forEach((movie, lines) -> {
Set<String> genres = lines.stream()
.flatMap(l -> Stream.of(l[2].split(",")))
.collect(Collectors.toSet());
System.out.println("movie: " + movie + " genres: " + genres);
});
这样做的好处是O(n)
而不是O(n^2)
,而且它是多线程的。
答案 1 :(得分:0)
进行哈希联接。
截至目前,您正在进行外部循环连接,即O(n ^ 2),散列连接将分摊O(n)
将每个文件的内容放在哈希映射中,键入您想要的字段(第二个字段)。
Map<String,String> map1 = new HashMap<>();
// build the map from file1
然后进行散列连接
for(String key1 : map1.keySet()){
if(map2.containsKey(key1)){
// do your thing you found the match
}
}