Mam mapę, w której klucze mogą również istnieć jako jedna z wartości. Muszę usunąć je z wartości. Napisałem metodę, która potrzebuję, to tylko mam ponad 80 tysięcy kluczy i zajmuje na zawsze.

static void cleanSetMap(Map<String, Set<String>> inputMap){
    List<String> keys = new ArrayList<>(inputMap.keySet());
    List<Set<String>> values = new ArrayList<>(inputMap.values());

    for (int i = 0; i < keys.size(); i++) {
        String key = keys.get(i);
        for (int j = 0; j < values.size(); j++) {
            Set<String> set = values.get(j);
            set.remove(key);
            values.set(j, set);
        }
    }

    for (int i = 0; i < keys.size(); i++) {
        inputMap.put(keys.get(i), values.get(i));
    }

}

Czy można to zrobić prostsze lub szybsze?

2
J.Doe 2 czerwiec 2018, 20:43

3 odpowiedzi

Najlepsza odpowiedź

Poniższe oświadczenie usunie każdy ciąg, który jest kluczem na mapie z dowolnych wszystkich zestawów, które są w nim wartości.

    inputMap.keySet().parallelStream().forEach(
         key -> inputMap.values().stream().forEach(set -> set.remove(key)));

Jest to tylko równoległy strumień we wszystkich wpisach map, uruchomiony inny sekwencyjny strumień na zestawach wartości, aby usunąć każdy klawisz.

Może być konieczne przetestowanie zachowania strumienia równoległego w tym przypadku. Jeśli Wartość Set Instancje nie są bezpieczne, być może powinieneś raczej zadzwonić inputMap.keySet().stream()... (ale w takim przypadku wewnętrzny strumień może być wykonany równolegle (key -> inputMap.values().parallelStream()...) jako Set.remove) nie zostanie wywołany jednocześnie na żadnej wartości mapy)

1
ernest_k 2 czerwiec 2018, 20:20

Patrząc w swój przykładowy kod, wydaje się, że szukasz usuwania wszystkich kluczy z zestawu wartości, nawet jeśli nie są one obecne w tej pary wartości kluczowej.

Możesz spróbować :

List<String> keys = new ArrayList<>(inputMap.keySet());
List<Set<String>> values = new ArrayList<>(inputMap.values());
Iterator<Set<String>> itr = values.iterator();
while (itr.hasNext()) {
    itr.next().removeAll(keys);
}
0
Ashish Patil 2 czerwiec 2018, 19:29

Myślę, że inna opcja byłaby wprowadzeniem bardziej pomocnych abstrakcji.

Znaczenie: Zamiast trzymania "surowej" mapy ciągu i zestawów strun, może być pomocne, aby użyć pewnego rodzaju indeksu na przykład.

Podobnie jak w: Pamiętaj, że dla każdego ciągu, w którym ustawiono go. Zamiast wprowadzać potrzebę iteracji wszystkich wartości w dużej mapie.

Punktem jest: W przypadku wyjmowania ciągów używanych jako klawiszy, aw tych zestawach wartości jest wspólną działaniem, po prostu wybierz typ danych, który pozwala to zrobić skutecznie.

Lub jeszcze dalej cofasz się dalej. Na przykład za pomocą pełnej wyszukiwarki tekstowej, takiej jak Solr. Na pewno takie struktury pozwalają na wydajne aktualizacje naprawdę duże wskaźniki.

0
GhostCat 2 czerwiec 2018, 19:36