theJava
theJava

Reputation: 15034

Couple of questions on ArrayList

Question1:

Does it make sense to specifiy the size of the ArrayList. I know how many elements is going to carry in my List, is it good to specify the size before hand or it does not even matter.

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

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

Question2:

The java.util.ConcurrentModificationException occurs when you manipulate (add,remove) a collection while iterating over the same collection. Does that mean there is a thread which is modifying the ArrayList and another Thread iterating the same object.

Question3

Can anyone tell me how i can lock a list?

Upvotes: 5

Views: 201

Answers (4)

rai.skumar
rai.skumar

Reputation: 10677

Regarding Question num 3: There are two ways to lock a list

1) Implicit monitor lock : If you create a synchronized list using factory method of collections then you can use the wrapper object to create lock.

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

in this case slist will be used for locking during iteration and any compound action.

2) You can use Object class as lock

    Object lock = new Object();
    synchronized (lock) {
       // ...
     }

Upvotes: 1

ceptno
ceptno

Reputation: 687

Q1: This is what the ArrayList might look like

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

when you construct an ArrayList, the size of the array is automatically initialized. When you run out of space, the size is automatically adjusted to 1.5 times the original size.

Q2: You are exactly right. "For example, it is not generally permissible for one thread to modify a Collection while another thread is iterating over it. In general, the results of the iteration are undefined under these circumstances. Some Iterator implementations (including those of all the general purpose collection implementations provided by the JRE) may choose to throw this exception if this behavior is detected. Iterators that do this are known as fail-fast iterators, as they fail quickly and cleanly, rather that risking arbitrary, non-deterministic behavior at an undetermined time in the future." -java doc http://docs.oracle.com/javase/1.5.0/docs/api/java/util/ConcurrentModificationException.html

Q3: To lock a list you use

Collections.unmodifiableList(list);

This works with all Collections, and it prohibits the user from altering the data. In other words it gives the user a "read-only" copy. You can read more about the collections class here. http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Collections.html

Upvotes: 1

Jon Skeet
Jon Skeet

Reputation: 1500635

  1. It matters if you're adding a lot of items, as it means the collection won't need to keep copying its internal buffer as it goes along. With a small list it won't make much difference. Note that you're not specifying the size of the ArrayList - you're specifying its initial capacity:

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

    You still need to add items to it to change the size - but you can add items up to its capacity before it needs to perform copying internally.

  2. No, there doesn't have to be an extra thread involved. It just means that you've modified the collection while you're iterating over it. That can very easily be in a single thread:

    for (String item : items) {
        items.add("Foo"); // The next iteration step will fail.
    }
    
  3. You'll need to give more context. Usually it makes more sense to obtain a lock while you perform some operations on a list.

Upvotes: 8

Adam Sznajder
Adam Sznajder

Reputation: 9206

  1. If the list will be big then yes it's worth to declare the initial size. Why? Because when you create an ArrayList it's initial size is often ~10. When you add new items and the initial size is not enough the ArrayList more memory is allocated and all elements are relocated what takes time.

  2. No it's not neccessary the another thread. This exception may occur when you iterate over a list and in the loop body you add or remove it's elements. You have then to use iterators.

  3. What do you mean by locking a list? You want to make it thread-safe or to disable adding/removing its elements? In the second case you would like to use unmodifiableCollection method in java.util.Collections.

Upvotes: 1

Related Questions