Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hidden Features of Java - ArrayList / instance initializers clarification

In the Hidden Features of Java question, I was interested in the answer about instance initializers.

I was wondering how to modify this line :

List<Integer> numbers = new ArrayList<Integer>(){{ add(1); add(2); }};

in order to make it perform the same job with nested Arraylists:

ArrayList<ArrayList<Integer>> numbers = ...

is that possible?

like image 614
Heisenbug Avatar asked May 26 '11 18:05

Heisenbug


3 Answers

List<Integer> numbers = new ArrayList<Integer>(){{ add(1); add(2); }};

I don't really recommend this approach, as it creates an (anonymous) class for no good reason.

Use either:

List<Integer> numbers = Arrays.asList(1, 2);

or

List<Integer> numbers = new ArrayList<Integer>(Arrays.asList(1, 2));

For 2 levels, you can use:

List<List<Integer>> numbers = Arrays.asList(Arrays.asList(1, 2), Arrays.asList(2,3,4));

With a static import you could even reduce it to this, if you really want to:

List<List<Integer>> numbers = asList(asList(1, 2), asList(2,3,4));
like image 174
Puce Avatar answered Oct 25 '22 02:10

Puce


Double-brace initialization got a lot less interesting for lists now that Arrays.asList takes varargs, you can do this instead:

List<List<Integer>> numbers = new ArrayList<List<Integer>>();
numbers.add(Arrays.asList(1,2));
numbers.add(Arrays.asList(3,4));

Or combine with double-brace initialization like this:

List<List<Integer>> numbers = new ArrayList<List<Integer>>() {{add(Arrays.asList(1,2)); add(Arrays.asList(3,4));}};

but whether it fits on one line depends on your project's code-formatting guidelines. This is so horribly verbose that alternatives start to look good. Like putting the numbers into a string and parsing it. Or switching to Scala, Groovy, or Clojure, all of whom support literal list syntax.

like image 42
Nathan Hughes Avatar answered Oct 25 '22 02:10

Nathan Hughes


And of course you can do the same for the inner ArrayLists:, though I think it becomes pretty unreadable...

    List<ArrayList<Integer>> numbers = new ArrayList<ArrayList<Integer>>()
    {
        {
            add(new ArrayList<Integer>()
            {
                {
                    add(1);
                    add(2);
                }
            });
            add(new ArrayList<Integer>()
            {
                {
                    add(1);
                    add(2);
                }
            });
        }
    };

though not wildly longer or worse than the conventional way (depending on your brace style!)

    List<ArrayList<Integer>> numbers = new ArrayList<ArrayList<Integer>>();
    ArrayList<Integer> list1 = new ArrayList<Integer>();
    ArrayList<Integer> list2 = new ArrayList<Integer>();
    list1.add(1);
    list1.add(2);
    list2.add(1);
    list2.add(2);
    numbers.add(list1);
    numbers.add(list2);

The Arrays.asList(1, 2) approach given in other answers seems nicest of all.

like image 34
DNA Avatar answered Oct 25 '22 03:10

DNA