java.util has two ArrayList classes

Introduction

Hello. It's Kecho. ** Do you guys use ArrayList? ** ** Of course I also use it a lot. There was one unexpected thing, so I will introduce it.

quiz

A runtime exception will occur in the following sources. Where is it?

String[] array = { "banana", "apple", "melon" }; //Create an array
List<String> list1 = Arrays.asList(array); //Creating a list from an array

List<String> list2 = new ArrayList<>();
list1.stream().forEach(e -> list2.add(e)); //Create a list with the same elements as list1

list1.add("lemon"); //Add to list1
list2.add("lemon"); //Add to list2

System.out.print(list1); //Output the result of list1
System.out.print(list2); //Output the result of list2

↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ The correct answer is ``` list1.add (" lemon ")` ``! The following exception will occur.

Exception in thread "main" java.lang.UnsupportedOperationException
	at java.base/java.util.AbstractList.add(AbstractList.java:153)
	at java.base/java.util.AbstractList.add(AbstractList.java:111)
	at Main2.main(Main2.java:44)

By the way, `list2.add ("lemon ")` is executed normally.

Why do I get an exception?

First, let's take a look at each class

System.out.println(list1.getClass()); // class java.util.Arrays$ArrayList
System.out.println(list2.getClass()); // class java.util.ArrayList

Both are ArrayList. ** But list1 is an ArrayList of the inner class of the Arrays class **

In other words, there are two ArrayList classes. (Doya)

What's in java.util.Arrays $ ArrayList?

Let's take a look inside Arrays. It's too long to write, but the class name declaration looks like this.

・ ・ ・
private static class ArrayList<E> extends AbstractList<E>
        implements RandomAccess, java.io.Serializable
    {
・ ・ ・

It is defined in the inner class. And the add method is not implemented in ArrayList.

So go look at the parent class AbstractList. (It is the class that was output in the error message)

・ ・ ・
public boolean add(E e) {
    add(size(), e);
    return true;
}
・ ・ ・
public void add(int index, E element) {
    throw new UnsupportedOperationException();
}
・ ・ ・

This is the culprit! !! It is implemented to throw an UnsupportedOperationException when called.

Why is this implementation ...

AbstractList is literally an abstract class, so it is a prerequisite class. Therefore, it seems that it is implemented to throw an exception when called without inheritance.

No, I feel that there is a way to change the implementation of the asList method as it becomes an interface, but ... Please tell me the detailed person ...

Summary

There are the following two ArrayLists in java.util ①class java.util.Arrays$ArrayListclass java.util.ArrayList

Note that ① raises an exception when calling the add method.

Recommended Posts

java.util has two ArrayList classes
Ruby's & has two opposite meanings, right?