2012-11-10 12 views
5

question1:Kilka pytań na ArrayList

Czy jest sens do specifiy rozmiar ArrayList. Wiem, ile elementów ma nosić na mojej liście, czy dobrze jest określić rozmiar przed ręką, czy nawet nie ma to znaczenia.

List<String> list = new ArrayList<String>(1); 
list.add("Hello"); 

List<String> newList = new ArrayList<String>(); 
newList.add("Hello"); 

question2:

java.util.ConcurrentModificationException występuje podczas manipulowania (dodawać, usuwać) kolekcji podczas iteracji po tej samej kolekcji. Does that mean there is a thread which is modifying the ArrayList and another Thread iterating the same object.

question3

Czy ktoś może mi powiedzieć jak mogę zablokować listę?

Odpowiedz

8
  1. To ma znaczenie jeśli dodajesz wiele elementów, ponieważ oznacza, że ​​kolekcja nie będzie musiał zachować kopiowanie bufora wewnętrznego jak to idzie w parze. Z małą listą nie zrobi to wielkiej różnicy. Pamiętaj, że nie jesteś określający wielkość z ArrayList- jesteś podając swój początkowy zdolności:

    List<String> list = new ArrayList<String>(10000); 
    System.out.println(list.size()); // 0 
    

    Trzeba jeszcze dodać elementy do niego, aby zmienić rozmiar - ale można dodać elementy do jego pojemności, zanim będzie konieczne wewnętrzne kopiowanie.

  2. Nie, nie musi występować dodatkowy wątek. Oznacza to po prostu, że zmodyfikowałeś kolekcję podczas iteracji. Które można bardzo łatwo być w jednym wątku:

    for (String item : items) { 
        items.add("Foo"); // The next iteration step will fail. 
    } 
    
  3. Musisz dać więcej kontekstu. Zwykle lepiej jest uzyskać blokadę podczas wykonywania niektórych operacji na liście z zakresu.

+0

@halex: Naprawiono, dzięki. –

1
  1. Jeśli lista będzie duża, to warto zadeklarować początkowy rozmiar. Czemu? Ponieważ podczas tworzenia tablicy ArrayList jej początkowy rozmiar wynosi często ~ 10. Po dodaniu nowych elementów i początkowej wielkości nie wystarcza ArrayList więcej pamięci jest alokowana i wszystkie elementy są przenoszone, co wymaga czasu.

  2. Nie jest to konieczne dla kolejnego wątku. Ten wyjątek może wystąpić podczas iteracji nad listą iw treści pętli można dodawać lub usuwać jej elementy. Musisz wtedy użyć iteratorów.

  3. Co masz na myśli, blokując listę? Chcesz uczynić go bezpiecznym dla wątków lub wyłączyć dodawanie/usuwanie jego elementów? W drugim przypadku chciałbyś użyć metody unmodifiableCollection w java.util.Collections.

+2

w pkt 1, nie jesteś określające początkową * Size * - jesteś określające początkową zdolność * *. 'size()' nadal zwróci 0 po zakończeniu budowy, nawet jeśli pojemność jest ogromna. –

+0

Przepraszam, nie jestem native speakerem i nie wiedziałem, że powinienem użyć słowa "pojemność". Dzięki za zawiadomienie! –

1

Q1: To właśnie ArrayList może wyglądać

public ArrayList{ 
    private int[] elementData; 
    private int size; 
} 

kiedy skonstruować ArrayList, rozmiar tablicy jest automatycznie zainicjowana. Kiedy zabraknie miejsca, rozmiar jest automatycznie dostosowywany do 1,5 raza rozmiaru pierwotnego.

Q2: Masz dokładnie rację. "Na przykład nie jest ogólnie dopuszczalne, aby jeden wątek modyfikował kolekcję, podczas gdy inny wątek iteruje nad nim.Odpowiedziowo, wyniki iteracji są niezdefiniowane w tych okolicznościach. Niektóre implementacje Iteratora (włączając te z całego zbioru ogólnego przeznaczenia implementacje dostarczone przez środowisko JRE) mogą zdecydować się na odrzucenie tego wyjątku, jeśli to zachowanie zostanie wykryte. Iteratory, które to robią, są nazywane iteratorami fail-fast, ponieważ szybko i czysto zawodzą, a raczej ryzykują arbitralne, niedeterministyczne zachowanie w nieokreślonym czasie. w przyszłości." -java doc http://docs.oracle.com/javase/1.5.0/docs/api/java/util/ConcurrentModificationException.html

Q3: Aby zablokować listę użyć

Collections.unmodifiableList(list); 

ten działa ze wszystkimi kolekcjami i zabrania użytkownikowi zmianę danych. Innymi słowy, daje użytkownikowi kopię "tylko do odczytu". Możesz przeczytać tutaj więcej o klasie kolekcji. http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Collections.html

1

Odnośnie pytań num 3: Istnieją dwa sposoby, aby zablokować listę

1) niejawny blokady monitora: Jeśli utworzyć zsynchronizowane listy za pomocą metody fabryki kolekcji można użyć opakowanie obiekt do utworzenia blokady.

List<T> list = new ArrayList<T>(); 
    List<T> slist = Collections.synchronizedList(list); 
    synchoronized(slist) { 
    //code 
    } 

w tym przypadku slist będzie używany do blokowania podczas iteracji i dowolnych złożonych akcji.

2) można wykorzystywać jako obiekt klasy zamkiem

Object lock = new Object(); 
    synchronized (lock) { 
     // ... 
    } 
Powiązane problemy