The main difference is that Collections.emptyList() returns an immutable list, i.e., a list to which you cannot add elements. (Same applies to the List.of() introduced in Java 9.)
In the rare cases where you do want to modify the returned list, Collections.emptyList() and List.of() are thus not a good choices.
I'd say that returning an immutable list is perfectly fine (and even the preferred way) as long as the contract (documentation) does not explicitly state differently.
In addition, emptyList() might not create a new object with each call.
Implementations of this method need not create a separate List object for each call. Using this method is likely to have comparable cost to using the like-named field. (Unlike this method, the field does not provide type safety.)
The implementation of emptyList looks as follows:
public static final <T> List<T> emptyList() {
return (List<T>) EMPTY_LIST;
}
So if your method (which returns an empty list) is called very often, this approach may even give you slightly better performance both CPU and memory wise.
Answer from aioobe on Stack OverflowThe main difference is that Collections.emptyList() returns an immutable list, i.e., a list to which you cannot add elements. (Same applies to the List.of() introduced in Java 9.)
In the rare cases where you do want to modify the returned list, Collections.emptyList() and List.of() are thus not a good choices.
I'd say that returning an immutable list is perfectly fine (and even the preferred way) as long as the contract (documentation) does not explicitly state differently.
In addition, emptyList() might not create a new object with each call.
Implementations of this method need not create a separate List object for each call. Using this method is likely to have comparable cost to using the like-named field. (Unlike this method, the field does not provide type safety.)
The implementation of emptyList looks as follows:
public static final <T> List<T> emptyList() {
return (List<T>) EMPTY_LIST;
}
So if your method (which returns an empty list) is called very often, this approach may even give you slightly better performance both CPU and memory wise.
Starting with Java 5.0 you can specify the type of element in the container:
Collections.<Foo>emptyList()
I concur with the other responses that for cases where you want to return an empty list that stays empty, you should use this approach.
Collections.emptyList() does not need to create a new object for each call; it's typical, as in OpenJDK, to just return the singleton EMPTY_LIST object. Additionally, it's clearer that you intend to mean an empty list rather than having forgotten to fill in a placeholder.
Use emptyList(); it's both faster (up to Java target level 1.9) and more readable.
What is the preferred Java 9 way of pointing to an empty and immutable list?
The difference is rather subtle so "preferred" depends on what you want to achieve. Some behavioral differences:
List.ofwill throw an exception oncontains(null)invocations.- You can deserialize
emptyList()on JDK 8 and previous, but notList.of.
In terms or conveying that you want an empty list, emptyList() might look better, but this is just a temporary convention. If developers start using List.of() (which is much shorter than Collections.emptyList()) then it will become a known and accepted way, it's just new. If you think about it, there are some constructs we use which do not always convey what they do by themselves, but we got accustomed to them.
So there is no strictly preferred way. If the behavior does not matter use whatever you want.
If you are using java 9 or later:
} else {
return List.of();
}
If you are stuck with some version of java before 9:
} else {
return Collections.emptyList();
}
Notes:
- These constructs are the most efficient, because they reuse an existing instance of an empty list, so each time you ask for an empty list, no new list gets created. However, object allocation in Java is very inexpensive, so this should not really be a concern.
- The list returned by either
List.of()orCollections.emptyList()is secretly immutable. By secretly I mean that it exposes mutation methods, but if you make the mistake of invoking any of those methods, you will be slapped with a runtime exception. In other, better languages than Java, (for example, in Scala,) there exist immutable / unmodifiable collections, but Java does not have such a thing out of the box. So, if you are sticking with Java in 2020, you are accepting the possibility that not all of your collections can be written to, despite the fact that they all look as if they can be written to. - In general, functions are meant to return immutable entities, so if you are invoking a function which returns a collection and then you intend to modify that collection, you are doing it wrong. If you really need a collection that you can modify, you should instead write your function so that it populates a mutable list that you pass to it as a parameter, so it is evident that you, as the owner of the mutable list, are free to further modify the list after the function returns.
Collections.emptyList() returns an immutable list, i.e., a list to which you cannot add elements if you want to perform any operation on your list, then create new instance of list and return it.
if (isValidLang(lang)) {
query.setParameter("lang", lang);
return query.getResultList();
} else {
return new ArrayList<Lookup>(); // return array list instance.
}
To represent an Empty List in Java (an ArrayList is a List), we use java.util.Collections.emptyList().
So you could use something like this:
Foo foo = new Foo("boo", (ArrayList) java.util.Collections.emptyList());
In case you need other ways to create a new list in java, see this answer How to make a new List in Java.
Now you may have mixed up Arrays with ArrayList, resulting in usage of an array like syntax, [], to create an ArrayList. But that too is off mark from the language specifications, and you can read more about how to create arrays from SO here, or as is always better, the standard java docs.
And, not related to your question, but you should always code to an interface.
Your class Foo has a wrong constructor name, the correct should be:
class Foo {
String ide;
ArrayList list;
public Foo(String ide, ArrayList list){
this.ide = ide;
this.list = list;
}
}
Your first solution is wrong because you are not passing an instance of ArrayList to the constructor. In order to create an empty ArrayList, you may use:
Foo one = new Foo("boo", new ArrayList());
You may rewrite the Foo class to use the generic type of List:
class Foo {
String ide;
List list;
public Foo(String ide, List list){
this.ide = ide;
this.list = list;
}
}
... and use the java.util.Collections.EMPTY_LIST to represent empty lists:
Foo one = new Foo("boo", Collections.EMPTY_LIST);
If you are going to use it somewhere else, you can return any implementation of List interface. The most used:
new ArrayList<>();
Also there are a few ways to return an immutable empty list (means that you can not modify it):
return Collections.emptyList();
return List.of(); // from java9
See difference between them List.of() or Collections.emptyList()
Also see more about List implementations
How about:
return new ArrayList<>();