Wyszukiwanie po wartości pola w liście obiektów

0

Dzień dobry.

Mam przykładowo ArrayListę zawierającą milion obiektów typu Osoba z polami imię. nazwisko, PESEL. Dostaję 1000 różnych PESELi i mam pobrać z tej listy te 1000 osób.
Jak to najszybciej zrobić? Najgorszym sposobem jest iterowanie 1000 razy po prawie całej liście i porównanie PESELu, do tej pory robiłem to tak, że iterowałem raz po liście, wpychałem wszystko do mapy z kluczem - PESELem i później robiłem 1000 razy geta z mapy po PESELu.

Z góry dzięki za pomoc.
Pozdrawiam.

0

A jakby trzeba było znaleźć 10 osób po PESELU, to też ustawiłbyś najpierw cały milion grzecznie zindeksowany po PESEL-u, żeby dopiero potem wybrać sobie z nich tę szczęśliwą dziesiątkę? ;) Mocny code smell. Nie znam kontekstu, ale chyba coś idzie nie tak o krok wcześniej. Prawdopodobnie w momencie tworzenia owej gargantuicznej ArrayList-y na milion elementów; już to jest wysoce podejrzane. Jeśli już, to już wówczas lepiej byłoby - na bieżąco - wyłapać osoby, o które chodzi, zmieniając zapytanie czy chociaż filtrując przed zapełnieniem listy... ew. przynajmniej od razu zindeksować je po numerach PESEL, zamiast potem przepakowywać tę kolekcję z jednej do drugiej. Kiedy pojawi się miliard osób, może nam pęknąć komputer.

0

Za pomocą lambdy:

osoby.stream().filter(o -> peselList.contains(o.getPesel())).collect(Collectors.toList());

gdzie peselList to lista z twoimi 1000 PESELi a osoby to te milion typków

Jeśli nie masz / nie chcesz javy 8, to zwykłą pętlą:

List<Osoba> result = new ArrayList<>();
for (Osoba o : osoby) {
    if (peselList.contains(o.getPesel())) {
        result.add(o);
    }
}

Pisałem z głowy więc mogą być błędy kompilacji XD chociaż nie powinny

EDIT: A jeśli te milion osób idzie z bazy danych to już najlepiej na poziomie zapytania ograniczyć rozmiar kolekcji

0

Takie rzeczy powinieneś robić po stronie bazy danych/podczas wczytywania danych do pamięci (z całą pewnością nie potrzebujesz przetwarzać milionów rekordów w jednej chwili).

Jeśli jednak z jakiegoś dziwnego powodu nie możesz tego uczynić, a dane masz posortowane po peselu, można by się pokusić np. o wyszukiwanie binarne* bądź budowane w pamięci jakiegoś drzewa (zamiast trzymania w liście), co powinno przyśpieszyć proces.

* luźny strzał: na pewno będzie miało średnią lepszą wydajność przy wyszukiwaniu pojedynczego elementu (O(log n) vs O(n), gdzie n = liczba obiektów w liście), nie jestem pewien jak z wyszukiwaniem wielu elementów.

0

Przykład był tylko po to, żeby znaleźć najlepszy sposób w takim lub podobnym przypadku, nie ma to nic wspólnego z projektem, a raczej z nauką lub ciekawością.
Nie boję się Javy 8, ale niestety na zajęciach nic na ten temat nie miałem. Na pewno będę używał tego rozwiązania. Czy znacie jeszcze jakieś fajne rzeczy z Javy 8? Poznałem jeszcze Optional.

1 użytkowników online, w tym zalogowanych: 0, gości: 1