This article is participating in “Java Theme Month – Java Debug Notes Event”, see < Event link > for more details.

Question: How to initialize with one line of codeArrayList

I want to create an ArrayList of multiple elements for testing. At the beginning, I do this:

ArrayList<String> places = new ArrayList<String>(); places.add("Buenos Aires"); Places. The add (" Cordoba "); places.add("La Plata");Copy the code

Then I refactor the code as follows:

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

Is there a better way to initialize an ArrayList?

Popular answers

Java 10 or later

var strings = List.of("foo", "bar", "baz");
Copy the code

This will create an immutable List, so it cannot be changed.

In most cases, that’s enough.

Java 9

If you’re using Java9, you can’t use the var keyword.

List<String> strings = List.of("foo", "bar", "baz")
Copy the code

Java 8 or older

List<String> strings = Arrays.asList("foo", "bar", "baz");
Copy the code

This will return a List of underlying arrays, so its length cannot be changed. That is to say, strings. The add (” test “) is an error (Java. Lang. UnsupportedOperationException).

But you can call list.set (…) So it’s still variable.

Implementation details:

ArrayList: java.util.ArrayList: java.util.ArrayList: Java.util. ArrayList: Java.util. ArrayList: Java.util. ArrayList: Java.util. ArrayList: Java.util. ArrayList: Java.util. ArrayList: Java.util. ArrayList: Java.util.

Static imports

Java 8 Arrays.asList can be made even shorter with static imports:

import static java.util.Arrays.asList; . List<String> strings = asList("foo", "bar", "baz");Copy the code

Any IDE will provide code hints

But I don’t recommend importing methods statically, because it can clutter up the code.

Use Streams

Why do we have to create a List?

For Java8 and later, you have the flexibility to use Stream:

Stream<String> strings = Stream.of("foo", "bar", "baz");
Copy the code

You can connect streams

Stream<String> strings = Stream.concat(Stream.of("foo", "bar"),Stream.of("baz", "qux"));
Copy the code

You can also convert a Stream to a List

import static java.util.stream.Collectors.toList; . var strings = Stream.of("foo", "bar", "baz").toList(); // Java 16 List<String> strings = Stream.of("foo", "bar", "baz").collect(toList()); // Java 8Copy the code

But it’s better to just use Stream rather than save it to a List.

If you must need a java.util.ArrayList

But you’d better not, as follows:

There are sections that require predefined values that need to be placed in collections. In general, it is best to place these predefined values in an immutable collection and then copy the constructor to initialize the mutable collection.

If you want to prepopulate an ArrayList and add elements later, use:

ArrayList<String> strings = new ArrayList<>(List.of("foo", "bar"));
strings.add("baz");
Copy the code

Using Java 8 or older:

ArrayList<String> strings = new ArrayList<>(asList("foo", "bar"));
strings.add("baz");
Copy the code

Use of the Stream

import static java.util.stream.Collectors.toCollection;

ArrayList<String> strings = Stream.of("foo", "bar")
                             .collect(toCollection(ArrayList::new));
strings.add("baz");
Copy the code

Say the important things twice! You are better off just using Stream rather than saving it to a List.

Use polymorphism: Write variable names as interfaces rather than implementation classes

For collections that initialize with initial values, it is best to set the variable type to the interface rather than the implementation class of that interface. So we can use polymorphism.

For example, in the examples below, if you initialize a collection as an ArrayList, you will not be able to pass that collection into the method below, whereas if you initialize a List you will.

// Iterable if you just need iteration, for (String s : strings): void method(Iterable<String> strings) { for (String s : strings) { ... } } // Collection if you also need .size(), .isEmpty(), or .stream(): void method(Collection<String> strings) { if (! strings.isEmpty()) { strings.stream()... } } // List if you also need .get(index): void method(List<String> strings) { strings.get(...) } // Don't declare a specific list implementation // unless you're sure you need it: void method(ArrayList<String> strings) { ??? // You don't want to limit yourself to just ArrayList }Copy the code

Another example is InputStream. Various streams are often used in actual development, such as FileInputStream, BufferedInputStream, etc. Therefore, streams are usually initialized as InputStream at the beginning, which is convenient to adapt to different needs.

The article translated from Stack Overflow:stackoverflow.com/questions/1…