我有一個List<Films> films,每部電影都有int id和String description。我的任務是將所有描述中的每個單詞映射到描述中包含該單詞的所有電影名稱,它必須是這樣的:
<word1>: <filmId11>, <filmId12>,..., <filmId1N>
<word2>: <filmId21>, <filmId22>, ..., <filmId2N>
...
我使用 Java Stream API 做到了:
private List<Map.Entry<String, String>> wordToFilmIds;
private void addWordsFromDescriptions(List<Film> films) {
for (Film film : films) {
String description = film.description();
String[] tokens = description.split("[\\p{IsPunctuation}\\p{IsWhite_Space}] ");
allWords.addAll(Arrays.stream(tokens).toList());
}
}
private void mapWordsToFilmIDs(List<Films> films) {
wordToFilmIds = allWords.stream()
.map(word -> Map.entry(word,
films.stream()
.filter(film -> film.description().contains(word))
.map(film -> String.valueOf(film.id()))
.collect(Collectors.joining(","))))
.toList();
}
但問題是我的解決方案太慢了,我必須處理大數字,電影的數量約為 12 000,描述也不短。另外,我被not允許使用multi-threading. 知道如何優化它嗎?現在程式還沒有完成。
我也試過用parallel streams,還是不行。
uj5u.com熱心網友回復:
我認為你為每個單詞迭代每部電影的事實使得解決方案 O(n^2)。不過,它可以通過一次迭代來實作:
給定助手類:
public class Tuple<A,B> {
public A a;
public B b;
public Tuple(A a, B b) {
this.a = a;
this.b = b;
}
}
試試這個:
Map<String, Set<Integer>> addWordsFromDescriptions(List<Film> films) {
return films.stream()
.flatMap(film -> tokenizeDescription(film).map(token -> new Tuple<>(token, film)))
.collect(Collectors.groupingBy(
tuple -> tuple.a,
Collectors.mapping(tuple -> tuple.b.id(), Collectors.toSet())
));
}
private Stream<String> tokenizeDescription(Film film) {
return Stream.of(film.description().split("[\\p{IsPunctuation}\\p{IsWhite_Space}] "));
}
給定Map<String, Set<Integer>>,您可以加入集合中的 id 并獲取您想要的字串。
uj5u.com熱心網友回復:
public static class Film {
private final String id;
private final String description;
public Film(String id, String description) {
this.id = id;
this.description = description;
}
public String getId() {
return id;
}
public String getDescription() {
return description;
}
}
public static void main(String... args) {
List<Film> films = List.of();
Map<String, Film> filmById = films.stream().collect(Collectors.toMap(Film::getId, Function.identity()));
Map<String, Set<String>> filmByLowerCaseDescriptionWord = createDescriptionMap(films);
}
private static Map<String, Set<String>> createDescriptionMap(List<Film> films) {
Map<String, Set<String>> map = new HashMap<>();
films.forEach(film -> Arrays.stream(film.getDescription().split("\\S "))
.map(word -> word.trim().toLowerCase(Locale.ROOT))
.forEach(lowerCaseWord ->
map.computeIfAbsent(lowerCaseWord, key ->
new HashSet<>()).add(film.getId())));
return map;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/404893.html
標籤:
上一篇:在Oracle中讀取執行計劃
