views:

13990

answers:

7

I am willing to create a list of options to test something.

I was doing:

ArrayList<String> places = new ArrayList<String>();
places.add("Buenos Aires");
places.add("Córdoba");
places.add("La Plata");

I refactor the code doing:

ArrayList<String> places = new ArrayList<String>(Arrays.asList("Buenos Aires", "Córdoba", "La Plata"));

Is there a better way of doing this?

Thanks for reading!

+21  A: 

Actually, probably the "best" way to initialize the ArrayList is the method you wrote, as it does not need to create a new List in any way:

ArrayList<String> list = new ArrayList<String>();
    list.add("A");
    list.add("B");
    list.add("C");

The catch is that there is quite a bit of typing required to refer to that list instance.

There are alternatives, such as making an anonymous inner class with an instance initializer (also known as an "double brace initialization"):

ArrayList<String> list = new ArrayList<String>() {{
    add("A");
    add("B");
    add("C");
}}

However, I'm not too fond of that method because what you end up with is a subclass of ArrayList which has an instance initializer, and that class is created just to create one object -- that just seems like a little bit overkill to me.

What would be nice is if the Collection Literals proposal for Project Coin is accepted, so we can have list literals in Java 7:

List<String> list = ["A", "B", "C"];

Unfortunately it won't help you here, as it will initialize a List rather than an ArrayList, and furthermore, it's not available yet, if it ever will be.

coobird
See http://stackoverflow.com/questions/924285/ for more information about the double-brace initialization, pros and cons.
Eddie
@Eddie: Good call for the link -- one sentence on double-brace initialization isn't enough to describe it fully.
coobird
Looking foward for the Collection Literals!
Macarse
@Macarse: I sure hope that collection literals make it to Java 7 :)
coobird
That collection literals is a nice nugget, thanks. I also hope it makes it into 7.
javamonkey79
+23  A: 

It'd be simpler if you were to just declare it as a List - does it have to be an ArrayList?

List<String> places = Arrays.asList("Buenos Aires", "Córdoba", "La Plata");
Tom
Yes, my class has an private ArrayList<String>.
Macarse
@Marcase: Can you not change your class to use a List instead of ArrayList?
Software Monkey
@Software Monkey: I wanted to know how to initialize an ArrayList. It's not real code, I was just testing things out. So, yes I might change it to List, but that would not answer my question.
Macarse
As per my answer, if you're not using methods specific to `ArrayList`, it would be better design to change the declaration to `List`. Specify interfaces, not implementations.
Christoffer Hammarström
A: 

You could create a factory method:

public static ArrayList<String> createArrayList(String ... elements) {
  ArrayList<String> list = new ArrayList<String>(); 
  for (String element : elements) {
    list.add(element);
  }
  return list;
}

....

ArrayList<String> places = createArrayList(
  "São Paulo", "Rio de Janeiro", "Brasília"); 

But it's not much better than your first refactoring.

UPDATE: for greater flexibility, it can be generic:

public static <T> ArrayList<T> createArrayList(T ... elements) { 
  ArrayList<T> list = new ArrayList<T>();  
  for (T element : elements) { 
    list.add(element); 
  } 
  return list; 
} 
Jordão
The convention for method names that almost everybody uses in Java is to start with a lower-case letter: `createArrayList` (not `Create...`)
Jesper
Oh so true, I just keep switching between C# and Java. I'll update the answer....
Jordão
+3  A: 
import com.google.common.collect.ImmutableList;

....

List<String> places = ImmutableList.of("Buenos Aires", "Córdoba", "La Plata");
George
I don't want to add a new dependency just to do that.
Macarse
Trust me it's worth it. Until they finally add this stuff to the Collections framework or people start using another JVM language altogether...
George
That's the same as `Collections.unmodifiableList(Arrays.asList("Buenos Aires", "Córdoba", "La Plata"))`, which becomes `unmodifiableList(asList("Buenos Aires", "Córdoba", "La Plata"))` with static imports. You don't need Google Collections for this.
Christoffer Hammarström
A: 

To setup a list filled with N copies of a default object:

ArrayList<Object> list = new ArrayList<Object>(
    Collections.nCopies(1000, new Object())); 
Vincent
That's not an empty list, that's a list with 1000 references to one object. Use `new ArrayList(1000)` if you want an empty list with reserved room for 1000 objects, otherwise it's just `new ArrayList()`.
Christoffer Hammarström
Hi, I need to rephrase that "setup an empty list" into a "list with 1000 objects". Point here was to have a list initialised and filled in one line and have size() return 1000 unlike new ArrayList(1000) which will have a capacity of 1000 elements but still be empty.
Vincent
A: 

Pretty much the simplest way is just List<String> strings = new ArrayList<String>(asList("foo", "bar", "baz")), if you must have an ArrayList, otherwise you should in most cases just use List<String> strings = asList("foo", "bar", "baz")

You said you've declared the list as an ArrayList in your code, but you should not do that unless you're using some member of ArrayList that's not in List, for example ArrayList.ensureCapacity().

Usually you should just declare variables by the most general interface that you are going to use, which for lists is usually List, and initialize them with the specific implementation, for example ArrayList or LinkedList.

Work with interfaces, not implementations, otherwise you will find that you have to change in more than one place when you want to use another implementation.

Another example would be always declaring variable an InputStream even though it is usually a FileInputStream, because one day soon you or somebody else will want to use some other kind of InputStream.

Christoffer Hammarström
A: 

Just observed it is working in a very simple way as follows:

 ArrayList arrList = new ArrayList() {"1",2,3,"4" };

List<Customer> listCustomer = new List<Customer>() { new Customer(), new Customer(), new Customer() };

This is working in C# 3.0 No Double Braces required. Hope this helps.

Subhasis
This question is about Java...
Pascal Thivent