Arrays. Is used in the project Aslist, subList, publicly criticized

Posted by PHP_apprentice on Wed, 19 Jan 2022 00:16:00 +0100

1. Use arrays Precautions for aslist

1.1 possible pits

Let's take a look at arrays Use of aslist:

List<Integer> statusList = Arrays.asList(1, 2);System.out.println(statusList);System.out.println(statusList.contains(1));System.out.println(statusList.contains(3));

The output results are shown in the figure below:

Then, add element 3 to the statusList as follows:

statusList.add(3);System.out.println(statusList.contains(3));

The expected result should be true, but the actual result is Java Lang.unsupported operationexception:

I can't help but wonder why it's unscientific to throw such an exception by simply adding an element.

1.2 cause analysis

With this question in mind, let's take a look at the source code of the static method asList provided by the Arrays class:

The returned is an ArrayList, which is very familiar and has wood. However, if you look carefully, you will find that this ArrayList is not the ArrayList we often use, because the ArrayList we often use is located in Java Under util package:

However, the ArrayList here is an internal class of the Arrays class:

It also inherits the AbstractList class and rewrites many methods, such as the contains method we used above, but does not override the add method, so we will throw Java. Net when we call the add method Lang.unsupported operationexception.

In this regard, it is also mentioned in the Taishan edition of Alibaba Java Development Manual:

Use the tool class arrays When aslist() converts an array into a collection, it cannot be used to modify the collection related methods. Its add/remove/clear method will throw an unsupported operationexception.

So people are using arrays You should pay attention when you step on the aslist to avoid stepping on the pit.

1.3 summary

Arrays. The aslist method can be used in some simple situations, such as quickly declaring a collection to judge whether a value is within the allowable range:

However, after the declaration, do not call add and other methods to modify the collection, otherwise it will report Java Lang.unsupported operationexception.

2. Precautions for using subList of ArrayList

Let's first look at the simple use of subList:

List<String> bookList = new ArrayList<>();bookList.add("Distant Savior");bookList.add("betray");bookList.add("Red dust of the sky");bookList.add("life");bookList.add("Ordinary world");
List<String> luyaoBookList = bookList.subList(3, 5);
System.out.println(bookList);System.out.println(luyaoBookList);

The operation results are shown in the figure below:

As can be seen from the running results, subList returns a collection of elements with indexes from fromIndex (included) to toIndex (not included) in bookList.

It is easy to use and easy to understand, but there are still the following points to pay attention to, otherwise it will cause program errors or exceptions:

  1. Modifying the value of the original set element will affect the subset

  2. Modifying the structure of the original collection will cause a ConcurrentModificationException

  3. Modifying the value of a subset element will affect the original set

  4. Modifying the structure of a subset will affect the original set

The above points are described in the Taishan edition of Alibaba Java Development Manual:

2.1 modifying the value of the original set will affect the subset

For example, let's modify the value of an element in the original collection bookList (non structural modification):

List<String> bookList = new ArrayList<>();bookList.add("Distant Savior");bookList.add("betray");bookList.add("Red dust of the sky");bookList.add("life");bookList.add("Ordinary world");
List<String> luyaoBookList = bookList.subList(3, 5);
System.out.println(bookList);System.out.println(luyaoBookList);
// Modify the value of the original collection booklist Set (3, "Luyao - life");
System.out.println(bookList);System.out.println(luyaoBookList);

The operation results are as follows:

It can be seen that although we only modified the value of the original set bookList, it affected the subset luyaoBookList.

2.2 modifying the structure of the original set will cause a ConcurrentModificationException

For example, we add an element (structural modification) to the original collection bookList:

List<String> bookList = new ArrayList<>();bookList.add("Distant Savior");bookList.add("betray");bookList.add("Red dust of the sky");bookList.add("life");bookList.add("Ordinary world");
List<String> luyaoBookList = bookList.subList(3, 5);
System.out.println(bookList);System.out.println(luyaoBookList);
// Add the element booklist to the original collection Add ("morning starts at noon");
System.out.println(bookList);System.out.println(luyaoBookList);

The operation results are as follows:

It can be seen that when we add elements (structural modifications) to the original set, a ConcurrentModificationException occurs when traversing the subset.

Note: the above exception does not occur when adding an element, but when traversing a subset after adding an element.

This is described in the Taishan edition of Alibaba Java Development Manual:

2.3 modifying the value of a subset will affect the original set

For example, we modify the value of an element in the subset luyaoBookList (non structural modification):

List<String> bookList = new ArrayList<>();bookList.add("Distant Savior");bookList.add("betray");bookList.add("Red dust of the sky");bookList.add("life");bookList.add("Ordinary world");
List<String> luyaoBookList = bookList.subList(3, 5);
System.out.println(bookList);System.out.println(luyaoBookList);
// Modify the value of the subset luyaobooklist Set (1, "Luyao - ordinary world");
System.out.println(bookList);System.out.println(luyaoBookList);

The operation results are as follows:

It can be seen that although we only modified the value of the subset luyaoBookList, it affected the original collection bookList.

2.4 modifying the structure of a subset will affect the original set

For example, we add an element (structural modification) to the subset luyaoBookList:

List<String> bookList = new ArrayList<>();bookList.add("Distant Savior");bookList.add("betray");bookList.add("Red dust of the sky");bookList.add("life");bookList.add("Ordinary world");
List<String> luyaoBookList = bookList.subList(3, 5);
System.out.println(bookList);System.out.println(luyaoBookList);
// Add the element luyaobooklist to the subset Add ("morning starts at noon");
System.out.println(bookList);System.out.println(luyaoBookList);

The operation results are as follows:

It can be seen that when we add elements (structural modifications) to the subset, the original collection bookList is affected.

2.5 cause analysis

First, let's take a look at the comments of the subList method to understand its purpose:

Returns a view of the portion of this list between the specified {@code fromIndex}, inclusive, and {@code toIndex}, exclusive.

Translation means:

Returns a view of the part of the list between the specified {@ code fromIndex} (inclusive) and {@ code toIndex} (exclusive).

Then, let's look at its source code:

public List<E> subList(int fromIndex, int toIndex) {    subListRangeCheck(fromIndex, toIndex, size);    return new SubList(this, 0, fromIndex, toIndex);}

You can see that it calls the constructor of SubList class. The source code of the constructor is shown in the following figure:

It can be seen that SubList class is an internal class of ArrayList, and a new ArrayList is not recreated in this constructor, so modifying the values of elements in the original set or subset will affect each other.

2.6 summary

The subList method of ArrayList returns a subset (view) of the original set. Non structural modification of the values of the elements of any set will affect each other. When structurally modifying the original set, a ConcurrentModificationException exception will be reported. When structurally modifying the subset, it will affect the original set. Therefore, pay attention to avoid program errors or exceptions.

Topics: Java Back-end