मेरे पास एक List<Films> films है, जहां प्रत्येक फिल्म में int id और String description हैं। मेरा काम प्रत्येक शब्द को सभी विवरणों से उन सभी फिल्मों के नामों में मैप करना है जिनमें विवरण में शब्द शामिल है, यह कुछ ऐसा होना चाहिए:

<word1>: <filmId11>, <filmId12>,..., <filmId1N>
<word2>: <filmId21>, <filmId22>, ..., <filmId2N>
...

मैंने इसे जावा स्ट्रीम एपीआई का उपयोग करके किया:

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 का उपयोग करने का भी प्रयास किया, फिर भी, यह काम नहीं कर रहा था।

1
vanderwaal 7 जिंदा 2022, 12:43
2
उल्टे अनुक्रमणिका के बारे में पढ़ें, फिर फिल्म विवरण में सभी शब्दों से एक HashMap<String, Set<Film>> बनाएं और अपने दुनिया बदल जाएगी।
 – 
Bohemian
7 जिंदा 2022, 13:07
मैं प्रोग्रामिंग के लिए नया हूं और मैंने इसके बारे में नहीं सुना है। आपका बहुत बहुत धन्यवाद!
 – 
vanderwaal
7 जिंदा 2022, 13:39

3 जवाब

सबसे बढ़िया उत्तर

मुझे लगता है कि तथ्य यह है कि आप प्रत्येक फिल्म पर प्रत्येक शब्द के लिए पुनरावृत्ति कर रहे हैं, समाधान ओ (एन ^ 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>> को देखते हुए, आप सेट में आईडी से जुड़ सकते हैं और अपनी मनचाही स्ट्रिंग प्राप्त कर सकते हैं।

1
Nikos Paraskevopoulos 7 जिंदा 2022, 13:30

कभी-कभी, for-each लूप streams की तुलना में अधिक साफ और पठनीय हो सकते हैं।

Java-8 ने {a href="https://docs.oracle.com/javase/8/docs/api/java/util/Map.html" rel="nofollow noreferrer">नया तरीके पेश किए Map इंटरफ़ेस; computeIfAbsent ऐसी स्थितियों के लिए उपयुक्त है:

Map<String, Set<Integer>> wordsToFilmIdMap = new HashMap<>();

for (Film film : films) {
   String[] filmDescArray = film.getDesc().split("[\\p{IsPunctuation}\\p{IsWhite_Space}]+");
   for (String descWord : filmDescArray) {
        wordsToFilmIdMap.computeIfAbsent(descWord, unused -> new HashSet<>()).add(film.getId());
   }
}
0
adarsh 8 जिंदा 2022, 14:35
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;
}
0
oleg.cherednik 7 जिंदा 2022, 13:35
आपका बहुत बहुत धन्यवाद!
 – 
vanderwaal
7 जिंदा 2022, 14:53