2015-05-15 13 views
7

Generuję listę Customer z pliku, który przeczytałem. Przechowywać tych klientów w HashMap gdzie klucz jest unikalny ID:Znaleźć pojedynczy obiekt w kolekcji, filtr HashMap i filtr listy

Map<String, Customer> customers = readCustomers(); //For each object created customers.put(c.getCustomerId(), c);

z drugiego pliku otrzymuję dane, które używam, aby zaktualizować obiekt w HashMap. I użyj klawisza, aby znaleźć obiekt do aktualizacji:

//get the details informations customers.get(customerId).setDetails(details);

w Java 8 mogłem użyć:

class Customer{ 
    ... 

    public static Customer find(List<Customer> customers, int id) { 
     return customers.stream().filter(c -> c.customerId == id).findAny().get(); 
    } 
} 

//usage 
List<Customer> customers = readCustomers();  
... 
Customer.find(customers, 21).setDetails(details); 

by tam być poprawa wydajności przy użyciu metody Java 8? Jaka jest najlepsza praktyka między tymi metodami?

Odpowiedz

12

Wyszukiwanie wartości kluczem w HashMapie wymaga O (1) oczekiwanego czasu, który jest szybszy niż O (n), który wymagałby wyszukiwania tej samej wartości na liście.

Korzystanie z Java 8 Streams nie zmienia tego, ponieważ za kulisami nowej, fantazyjnej składni nadal iteruje się nad elementami listy aż do znalezienia dopasowania.

+0

Po prostu z czystej ciekawości, czy wiesz, czy nowa, fantastyczna składnia sprawiłaby, że jvm byłby wystarczająco inteligentny, by wyszukiwać w bardziej "sprytny" sposób, czy też wciąż byłby taki sam, jak gdyby był w pętla? – david99world

+1

@David Jeśli używasz strumienia równoległego, wyszukiwanie może być wykonywane jednocześnie na wielu wątkach, ale nadal nie pokonuje HashMap. – Eran

+2

"przyjmuje O (1) przewidywany czas" nie ma sensu, ponieważ O (1) nie jest jednostką czasu, podczas gdy "która jest szybsza niż O (n)" jest po prostu * błędna *. Prawidłowe stwierdzenie jest takie, że złożoność czasu O (1) * skaluje się lepiej * niż O (n) dla "dużych wartości * n *". Jednak wniosek, że użycie strumienia API do wykonania wyszukiwania liniowego nie oznacza, że ​​poprawa jest nadal poprawna. Nie tylko dlatego, że nie skaluje się dobrze dla dużych * n * s, ale także dlatego, że '.get (customerId)' jest dużo bardziej czytelny niż '.stream(). Filter (c -> c.customerId == id) .findAny() .get() '. – Holger