First look and then like, give yourself a little time to think, wechat search [Silent King 2] focus on this talented programmer. This article has been collected at GitHub github.com/itwanger, along with interview questions compiled by top companies, and my series of articles.
Immutable List, as the name suggests, is, what, Immutable is? Immutable List is an Immutable List class, which means that a List is mutable and cannot be added, deleted, or altered after it is declared.
If you’re new to immutable classes, you can check out another article I wrote earlier by clicking on the link below.
How can I not understand immutable this time
If you try to add, delete, or update the elements in the List, it throws an UnsupportedOperationException anomalies.
In addition, elements in an Immutable List are non-null. If you use NULL to create an Immutable List, a NullPointerException will be thrown. If you try to null element is added in the Immutable List, will throw an UnsupportedOperationException.
So what’s an Immutable List good for?
- It is thread-safe;
- It’s efficient;
- Because it is immutable, it can be passed to third-party libraries just like String without any security issues.
Let’s look at how to create an Immutable List. Note that the source code is based on JDK14.
01. Use the native JDK
The Collections classes unmodifiableList () method can create a similar to the Immutable List unmodifiableList or UnmodifiableRandomAccessList, is Immutable.
public static <T> List<T> unmodifiableList(List<? extends T> list) {
return (list instanceof RandomAccess ?
new Collections.UnmodifiableRandomAccessList<>(list) :
new Collections.UnmodifiableList<>(list));
}
Copy the code
Here’s how to use it:
List<String> list = new ArrayList<>(Arrays.asList("Silent King II."."Silent King three."."The Silent King iv."));
List<String> unmodifiableList = Collections.unmodifiableList(list);
Copy the code
We tried adding the element “Silent King” to the unmodifiableList:
unmodifiableList.add("The Silent Five.");
Copy the code
After the operation will throw an UnsupportedOperationException anomaly:
Exception in thread "main" java.lang.UnsupportedOperationException
at java.base/java.util.Collections$UnmodifiableCollection.add(Collections.java:1062)
at com.cmower.mkyong.immutablelist.ImmutableListDemo.main(ImmutableListDemo.java:16)
Copy the code
02. With Java 9
In Java 9, the List class added a static factory method of() that can be used to create immutable lists. Take a look at the source code:
static <E> List<E> of(E e1, E e2, E e3) {
return new ImmutableCollections.ListN<>(e1, e2, e3);
}
Copy the code
The of() method has many variations, such as:
static <E> List<E> of(E e1) {
return new ImmutableCollections.List12<>(e1);
}
static <E> List<E> of(E e1, E e2) {
return new ImmutableCollections.List12<>(e1, e2);
}
static <E> List<E> of(E e1, E e2, E e3, E e4) {
return new ImmutableCollections.ListN<>(e1, e2, e3, e4);
}
static <E> List<E> of(E e1, E e2, E e3, E e4, E e5) {
return new ImmutableCollections.ListN<>(e1, e2, e3, e4, e5);
}
static <E> List<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10) {
return new ImmutableCollections.ListN<>(e1, e2, e3, e4, e5,
e6, e7, e8, e9, e10);
}
Copy the code
The designers of this method are also interesting. The arguments to the of() method, from 0 to 10, have an overloaded method with the same signature.
Even when arguments are mutable, we use the switch statement to determine the number of arguments and then call different overloaded methods:
static <E> List<E> of(E... elements) {
switch (elements.length) { // implicit null check of elements
case 0:
@SuppressWarnings("unchecked")
var list = (List<E>) ImmutableCollections.ListN.EMPTY_LIST;
return list;
case 1:
return new ImmutableCollections.List12<>(elements[0]);
case 2:
return new ImmutableCollections.List12<>(elements[0], elements[1]);
default:
return new ImmutableCollections.ListN<>(elements);
}
}
Copy the code
Whether ImmutableCollections. List12 or ImmutableCollections. ListN, they are final, and inherited AbstractImmutableList, the inside of the element is final.
static final class List12<E> extends ImmutableCollections.AbstractImmutableList<E>
implements Serializable {
@Stable
private final E e0;
@Stable
private final E e1;
}
static final class ListN<E> extends ImmutableCollections.AbstractImmutableList<E>
implements Serializable {
// EMPTY_LIST may be initialized from the CDS archive.
static @StableList<? > EMPTY_LIST;
static {
VM.initializeFromArchive(ImmutableCollections.ListN.class);
if (EMPTY_LIST == null) {
EMPTY_LIST = new ImmutableCollections.ListN<>();
}
}
@Stable
private final E[] elements;
}
Copy the code
Ok, let’s see how to use it:
final List<String> unmodifiableList = List.of("Silent King II."."Silent King three."."The Silent King iv.");
unmodifiableList.add("The Silent Five.");
Copy the code
ImmutableCollections inner class ListN or List12 is also non-modifiable, and adding elements using the add() method will also raise an exception at runtime:
Exception in thread "main" java.lang.UnsupportedOperationException
at java.base/java.util.ImmutableCollections.uoe(ImmutableCollections.java:73)
at java.base/java.util.ImmutableCollections$AbstractImmutableCollection.add(ImmutableCollections.java:77)
at com.cmower.mkyong.immutablelist.ImmutableListDemo.main(ImmutableListDemo.java:20)
Copy the code
03. With Guava
The Guava project contains several core libraries that are widely relied upon by Google’s Java project, such as: Collections, Caching, Primitives support, Concurrency Libraries, Common Annotations , string processing, I/O, etc. All of these tools are being used every day by Google engineers in products and services.
In the real world, the Guava library is used quite frequently, so we need to introduce Guava’s Maven dependency in the project first.
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>28.1 the jre</version>
</dependency>
Copy the code
Guava defines an ImmutableList class, which is declared as follows:
@GwtCompatible(serializable = true, emulated = true)
@SuppressWarnings("serial") // we're overriding default serialization
public abstract class ImmutableList<E> extends ImmutableCollection<E>
implements List<E>, RandomAccess {
}
Copy the code
Its class structure is as follows:
java.lang.Object
↳ Java. Util. AbstractCollection
↳ com.google.com mon. Collect. ImmutableCollection
↳ com.google.com mon. Collect. ImmutableList
Copy the code
The copyOf() method of the ImmutableList class can be used to create an ImmutableList object:
List<String> list = new ArrayList<>(Arrays.asList("Silent King II."."Silent King three."."The Silent King iv."));
List<String> unmodifiableList = ImmutableList.copyOf(list);
unmodifiableList.add("The Silent Five.");
Copy the code
ImmutableList is also not allowed to add elements to the add () method at the time of execution will throw an UnsupportedOperationException anomaly:
Exception in thread "main" java.lang.UnsupportedOperationException
at com.google.common.collect.ImmutableCollection.add(ImmutableCollection.java: 244).
at com.cmower.mkyong.immutablelist.ImmutableListDemo.main(ImmutableListDemo.java: 25)
Copy the code
The of() method of the ImmutableList class is similar to the of() method of Java 9. There are also a number of overloaded methods with the same signature that use exactly the same methods:
List<String> unmodifiableList = ImmutableList.of("Silent King II."."Silent King three."."The Silent King iv.");
Copy the code
The ImmutableList class also provides the Builder mode, which can either add elements at creation time, build on an existing List, or mix the two together.
ImmutableList<String> iList = ImmutableList.<String>builder()
.add("Silent King II."."Silent King three."."The Silent King iv.")
.build();
List<String> list = List.of("Silent King II."."Silent King three."."The Silent King iv.");
ImmutableList<String> iList = ImmutableList.<String>builder()
.addAll(list)
.build();
List<String> list = List.of("Silent King II."."Silent King three."."The Silent King iv.");
ImmutableList<String> iList = ImmutableList.<String>builder()
.addAll(list)
.add("The Silent Five.")
.build();
Copy the code
04, Collections. UnmodifiableList () and ImmutableList what’s the difference?
Collections. UnmodifiableList () based on the original List to create an immutable wrapper, the wrapper is immutable, but, we can modify the original List, thus affect the wrapper, look at the example below:
List<String> list = new ArrayList<>();
list.add("Silent King II.");
List<String> iList = Collections.unmodifiableList(list);
list.add("Silent King three.");
list.add("The Silent King iv.");
System.out.println(iList);
Copy the code
The output of the program is as follows:
King Of Silence ii, King of Silence III, King of Silence IV
Copy the code
But if we create an ImmutableList using the ImmutableList class, the ImmutableList will not be affected by the change in the List.
List<String> list = new ArrayList<>();
list.add("Silent King II.");
ImmutableList<String> iList = ImmutableList.copyOf(list);
list.add("Silent King three.");
list.add("The Silent King iv.");
System.out.println(iList);
Copy the code
The output of the program is as follows:
[The Silent King ii]
Copy the code
This is because ImmutableList is copied from the existing List.
I am the Silent King 2, a programmer with good looks but mediocre talent. Attention can improve learning efficiency, don’t forget three even ah, like, favorites, leave a message, I don’t pick, Ollie.
Note: If there are any problems with the article, please kindly correct them.
If you feel the article to you some help welcome wechat search “silent king ii” first time to read, reply to “small white” more have my liver 40,000 + words Java small white manual 2.0 version, this article GitHub github.com/itwanger has included, welcome star.