60

Can someone please provide an example of creating a Java ArrayList and HashMap on the fly? So instead of doing an add() or put(), actually supplying the seed data for the array/hash at the class instantiation?

To provide an example, something similar to PHP for instance:

$array = array (3, 1, 2);
$assoc_array = array( 'key' => 'value' );
Michael
  • 41,989
  • 11
  • 82
  • 128
Steve M
  • 10,517
  • 12
  • 52
  • 63

8 Answers8

114
List<String> list = new ArrayList<String>() {
 {
    add("value1");
    add("value2");
 }
};

Map<String,String> map = new HashMap<String,String>() {
 {
    put("key1", "value1");
    put("key2", "value2");
 }
};
bruno conde
  • 47,767
  • 15
  • 98
  • 117
  • 3
    These approaches are good. But the contents can be modified after creation. Immutable approachs are sooooo nice! – Steve McLeod May 12 '09 at 14:13
  • 9
    this is sometimes dangerous. you will get a reference to the enclosing class since the anonymous inner class maintains a reference to its parent object. this may cause problems with garbage collection and serialisation. – Andreas Petersson May 12 '09 at 14:29
  • 5
    I do not like double-brace initialization at all. Why create a new (non-static) inner class when a simple initializer will do just as well? – Michael Myers May 12 '09 at 14:57
  • I've always thought that the double brace approach was nice (esp for GUI construction) - but the comment on the parent object reference is very well made. Proceed with caution here. Might be better to make up a little Map builder class that accepts a vararg of objects (key, value, key value, etc...). – Kevin Day May 13 '09 at 04:44
  • Is there any performance issues? I mean, you create each time an anonimous class, that extend ArrayList. If you will create arraylist instance, and than add items into it, think it will be more cool for performance. Or this classes appear after compilation? – degr Jul 09 '15 at 08:47
  • If you create it like this then it can't be serialized anymore! – clankill3r Aug 11 '15 at 15:30
39

A nice way of doing this is using List.of() (since Java 8) and Map.of() (since Java 9):

List<String> list = List.of("A", "B", "C");
    
Map<Integer, String> map = Map.of(1, "A",
                                  2, "B",
                                  3, "C");

Java 7 and earlier may use Google Collections:

List<String> list = ImmutableList.of("A", "B", "C");

Map<Integer, String> map = ImmutableMap.of(
  1, "A",
  2, "B",
  3, "C");
Bill K
  • 62,186
  • 18
  • 105
  • 157
Steve McLeod
  • 51,737
  • 47
  • 128
  • 184
  • 2
    500kB is a high price to pay just to do that. If the only thing wanted is to fill the Collection on the fly, the accepted answer is IMHO nicest. – Damien B May 12 '09 at 14:23
  • Another reason to dislike this approach is that it's an immutable list, though I'm guessing (without having read the documentation) that there is a mutable list? – cgp May 12 '09 at 14:52
  • It's immutable by design! But yes, there are other options too. If it's immutable you can easily share one instance between threads, and therefore between web requests. 500 Kb is a high price to pay. But there are so many other goodies in the Google Collectons, it's worth paying the price. – Steve McLeod May 12 '09 at 14:55
  • @Damien- Fair enough, but nothing's stopping users from writing their own version of this method. – Philip Guin Dec 14 '12 at 12:41
  • 9
    Map.of is Java 9 feature not 8! – vahid kh Jun 20 '21 at 09:47
32

Arrays can be converted to Lists:

List<String> al = Arrays.asList("vote", "for", "me"); //pandering

Note that this does not return an ArrayList but an arbitrary List instance (in this case it’s an Array.ArrayList)!

Bruno's approach works best and could be considered on the fly for maps. I prefer the other method for lists though (seen above):

Map<String,String> map = new HashMap<String,String>() {
 {
    put("key1", "value1");
    put("key2", "value2");
 }
};
Bombe
  • 81,643
  • 20
  • 123
  • 127
cgp
  • 41,026
  • 12
  • 101
  • 131
  • 6
    be warned, Arrays.asList does not return an java.util.ArrayList but a fixed-size java.util.Arrays$ArrayList! – user85421 May 12 '09 at 14:00
8

for short lists:

    List<String> ab = Arrays.asList("a","b");
Andreas Petersson
  • 16,248
  • 11
  • 59
  • 91
  • not really.. from java.util.Arrays.java: public static List asList(T... a) { return new ArrayList(a); } so it just returns a pre-initialized ArrayList – Andreas Petersson May 12 '09 at 14:27
  • 3
    Look further in the source. Arrays has its own internal ArrayList class which doesn't support add() or remove(). – Michael Myers May 12 '09 at 14:33
  • 1
    and from the documentation of asList: "Returns a fixed-size list backed by the specified array." – user85421 May 12 '09 at 15:32
7

Use a nice anonymous initializer:

List<String> list = new ArrayList<String>() {{
    add("a");
    add("b");
}};

Same goes for a Map:

Map<String, String> map = new HashMap<String, String>() {{
    put("a", "a");
    put("b", "b");
}};

I find this the most elegant and readable.

Other methods demand creating an array first, then converting it to a List - too expensive in my taste, and less readable.

Yuval Adam
  • 161,610
  • 92
  • 305
  • 395
5

For lists you can use Arrays.asList like this:

List<String> stringList = Arrays.asList("one", "two");
List<Integer> intList = Arrays.asList(1, 2);

For Maps you could use this:

public static <K, V> Map<K, V> mapOf(Object... keyValues) {
    Map<K, V> map = new HashMap<>();

    K key = null;
    for (int index = 0; index < keyValues.length; index++) {
        if (index % 2 == 0) {
            key = (K)keyValues[index];
        }
        else {
            map.put(key, (V)keyValues[index]);
        }
    }

    return map;
}

Map<Integer, String> map1 = mapOf(1, "value1", 2, "value2");
Map<String, String> map2 = mapOf("key1", "value1", "key2", "value2");

Note: in Java 9 you can use Map.of
Note2: Double Brace Initialization for creating HashMaps as suggested in other answers has it caveats

R. Oosterholt
  • 7,720
  • 2
  • 53
  • 77
3

You mean like this?

public List<String> buildList(String first, String second)
{
     List<String> ret = new ArrayList<String>();
     ret.add(first);
     ret.add(second);
     return ret;
}

...

List<String> names = buildList("Jon", "Marc");

Or are you interested in the ArrayList constructor which takes a Collection<? extends E>? For example:

String[] items = new String[] { "First", "Second", "Third" };
// Here's one way of creating a List...
Collection<String> itemCollection = Arrays.asList(items);
// And here's another
ArrayList<String> itemList = new ArrayList<String>(itemCollection);
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • A slight improvement on Jon's suggestion: works for any number of items: public List buildList(String... items) { return new ArrayList(Arrays.asList(items)); } – Steve McLeod May 12 '09 at 13:40
  • (The example code could be simplified a little by making use of varags Arrays.asList(); http://stackoverflow.com/questions/258954/java-out-with-the-old-in-with-the-new/635078#635078) – Jonik May 12 '09 at 13:41
  • I was showing the separate steps to make it obvious how to do things when you'd already got an array. – Jon Skeet May 12 '09 at 14:40
  • Why not use var-args so you can pass any number of items? – sal May 12 '09 at 14:51
0

How about this?

ArrayList<String> array = new ArrayList<String>(Arrays.asList("value1", "value2"));

I know many of the answers provided similar solutions, but I think this one is a little more exact and more succinct. If you have lots of values, you might wanna do this:

ArrayList<String> array = new ArrayList<String>(Arrays.asList(
    "value1",
    "value2",
    "value3",
    ...
));
ahmadPH
  • 135
  • 11