2008-09-11 12 views
6

Podczas tworzenia klas w Javie często znajduję siebie tworząc kolekcje na poziomie instancji, które z wyprzedzeniem będą bardzo małe - mniej niż 10 elementów w kolekcji. Ale nie znam liczby elementów z wyprzedzeniem, więc zazwyczaj wybieram kolekcję dynamiczną (ArrayList, Vector itd.).Używanie małych (1-10 elementów) kolekcji na poziomie instancji w Javie

class Foo 
{ 
    ArrayList<Bar> bars = new ArrayList<Bar>(10); 
} 

Część mnie wciąż dręczy mnie, że marnowanie zasobów na tak małe rozmiary jest skomplikowane. Czy istnieje lepszy sposób realizacji czegoś takiego? Czy to jest norma?

Uwaga, nie dostaję żadnych (zauważalnych) kar za wydajność ani nic w tym stylu. Po prostu zastanawiam się, czy nie ma lepszego sposobu na robienie rzeczy.

Odpowiedz

11

Klasa ArrayList w Javie ma tylko dwa elementy danych, odwołanie do tablicy Object[] i rozmiar, który i tak jest potrzebny, jeśli nie używasz ArrayList. Tak więc jedyną korzyścią wynikającą z nieużywania ArrayList jest zapisanie jednej alokacji obiektów, co prawdopodobnie nigdy nie będzie dużym problemem.

Jeśli tworzysz i usuwania wielu, wielu wystąpień klasy kontenera (a co za tym idzie instancję ArrayList) co drugie, potędze mają niewielki problem ze zbieraniem śmieci rezygnacji, ale to jest coś się martwić jeśli kiedykolwiek się pojawi. Wyrzucanie śmieci jest zazwyczaj najmniejszym z twoich zmartwień.

+0

Obecne maszyny JVM optymalizują się w dużym stopniu w zakresie przydzielania obiektów, a kwestie związane z usuwaniem odpadów są prawie zawsze bezpodstawne. –

1

Narzut jest bardzo mały. Możliwe jest zapisanie listy tablic hybrydowych, która zawiera pola dla pierwszych kilku elementów, a następnie powraca do korzystania z tablicy dla dłuższej listy.

Możesz całkowicie uniknąć obciążenia obiektu listy za pomocą tablicy. Aby przejść jeszcze dalej, możesz zadeklarować pole jako obiekt i całkowicie uniknąć tablicy w przypadku pojedynczego elementu.

Jeśli pamięć naprawdę jest problemem, możesz zapomnieć o użyciu instancji obiektu na niskim poziomie. Zamiast tego użyj większej struktury danych na większym poziomie szczegółowości.

+0

Nic, co mówisz, jest złe, per se, ale nie chciałbym robić żadnej z tych rzeczy. Złożoność w jakiś sposób dynamicznie przechodząca między obiektem -> array -> ArrayList jest tak wielka, a koszt stworzenia prostego ArrayList tak małego, że myślę, że to tylko złe sugeruje –

+0

To rzadko ważne, ale kiedy jest ważne można go naprawić. Na przykład, javac robi dziwne rzeczy, aby utrzymać pamięć używaną przez łańcuchy, więc wszyscy korzystamy z szybszych, mniejszych kompilacji. –

3

W trosce o zachowanie prostoty, myślę, że to w zasadzie nie problem. Twoja implementacja jest na tyle elastyczna, że ​​jeśli wymagania zmienią się w przyszłości, nie będziesz zmuszony do refaktoryzacji. Dodanie większej logiki do kodu dla rozwiązania hybrydowego nie jest opłacalne biorąc pod uwagę twój mały zestaw danych i wysokiej jakości Java Collection API.

2

Google Collections ma kolekcje zoptymalizowane pod kątem niezmiennej/niewielkiej liczby elementów. Zobacz Lists.asList API jako przykład.