Java container Class Analysis: Collection, List, ArrayList,
1. Iterable and Iterator
Iterable is an interface that enables the collection object to traverse its own elements through the iterator.
Public interface Iterable <T>
Modifier and Return Value |
Method Name |
Description |
Iterator <T> |
Iterator() |
Returns an iterator whose internal elements are T type. |
Default void |
ForEach(Consumer <? Super T> action) |
Traverse internal elements and perform specified operations on the Elements |
Default Spliterator <T> |
Spliterator() |
Create and return a split iterator |
The first interface iterator () is introduced by jdk1.5 and requires sub-classes to implement an internal Iterator iterator traversal element.
The last two interfaces are newly added after jdk1.8. forEach (Consumer action) is used to facilitate the traversal of elements in the operation set. spliterator () provides an iterator that can traverse elements in parallel, to meet the requirements of parallel traversal in the current multi-core cpu era.
Here, we can lookDefaultModifier, which is new after Java 8. We know that if we add a new method to an interface, all its specific subclasses must implement this method, in order to expand new functions for the interface without the need for every subclass to implement this method, Java 8 adds the default keyword, and the method to be modified by it does not need to be implemented by the subclass, the method modified by dafault has a method body in the interface, which breaks the interface method specification before Java.
Iterator is an Iterator class used to traverse containers.
Public interface Iterator <E>
Modifier and Return Value |
Method Name |
Description |
Boolean |
HasNext () |
Judge whether the element referred to by the iterator is the last one |
E |
Next () |
Next Element |
Default Void |
Remove () |
Remove only the current element of the iterator |
Default Void |
ForEachRemaining (Consumer <? Super E> action) |
The iterator points to all elements behind the element. |
AbstartList implements the Iterator class as the List internal Iterator for accessing internal elements. Its code is as follows:
1 private class Itr implements Iterator<E> { 2 /** 3 * Index of element to be returned by subsequent call to next. 4 */ 5 int cursor = 0; 6 7 /** 8 * Index of element returned by most recent call to next or 9 * previous. Reset to -1 if this element is deleted by a call 10 * to remove. 11 */ 12 int lastRet = -1; 13 14 /** 15 * The modCount value that the iterator believes that the backing 16 * List should have. If this expectation is violated, the iterator 17 * has detected concurrent modification. 18 */ 19 int expectedModCount = modCount; 20 21 public boolean hasNext() { 22 return cursor != size(); 23 } 24 25 public E next() { 26 checkForComodification(); 27 try { 28 int i = cursor; 29 E next = get(i); 30 lastRet = i; 31 cursor = i + 1; 32 return next; 33 } catch (IndexOutOfBoundsException e) { 34 checkForComodification(); 35 throw new NoSuchElementException(); 36 } 37 } 38 39 public void remove() { 40 if (lastRet < 0) 41 throw new IllegalStateException(); 42 checkForComodification(); 43 44 try { 45 AbstractList.this.remove(lastRet); 46 if (lastRet < cursor) 47 cursor--; 48 lastRet = -1; 49 expectedModCount = modCount; 50 } catch (IndexOutOfBoundsException e) { 51 throw new ConcurrentModificationException(); 52 } 53 } 54 55 final void checkForComodification() { 56 if (modCount != expectedModCount) 57 throw new ConcurrentModificationException(); 58 } 59 } 60
View Code2, Collection
Collection is an interface of the container class, which can store a lot of Elements. Many containers have implemented this interface.
Public interface Collection <E> extends Iterable <E>
Modifier and Return Value |
Method Name |
Description |
Int |
Size () |
Determine the container size |
Boolean |
IsEmpty () |
Empty |
Boolean |
Contains (Object o) |
Whether it contains an element |
Object [] |
ToArray () |
Convert to array |
<T> T [] |
ToArray (T []) |
Copy all elements in the container to a. If a is not large enough, copy the elements to the returned array. (See Implementation in AbstactCollection) |
Boolean |
Add (E) |
Add Element |
Boolean |
Remove (Object o) |
Remove the first occurrence Object in the container. if the Object is null, remove the first occurrence of null. If no Object exists, false is returned. |
Boolean |
ContainsAll (Collection <?> C) |
Contains all elements in c |
Boolean |
AddAll (Collection <? Extends E> c ); |
Add all elements in c to the container |
Boolean |
RemoveAll (Collection <?> C) |
If the container contains elements in c, delete it. (Call remove (Object )) |
Default boolean |
RemoveIf (Predicate <? Super E> filter) |
Remove all qualified elements (introduced in JDK1.8) |
Boolean |
RetainAll (Collection <?> C) |
The elements that appear in c are retained, and all others are removed. |
Boolean |
Clear () |
|
Boolean |
Equals (Object o) |
Equal to all elements in o |
Int |
HashCode () |
C1.equals (c2) then their hashCode () must be equal, and vice versa |
Default Spliterator <E> |
Spliterator () |
Create a Spliterator on top of all elements |
Default Stream <E> |
Stream () |
|
Default Stream <E> |
ParallelStream () |
|
For the implementation of many of the above functions, refer to the implementation in AbstactList.
3. List
List is an interface that inherits all interfaces in Collection and adds related interfaces and implementations.
It can be seen that Collection is divided into three branches, and List is one of them. Next we will analyze the added interfaces in detail.
Public interface List <E> extends Collection <E>
Modifier and Return Value |
Method Name |
Description |
|
All interfaces in Collection |
|
Default void |
ReplaceAll (UnaryOperator <E> operator) |
Replace the result after the operation with the original elements in the List. |
Default void |
Sort (Comparator <? Super E> c) |
Sort all elements in the List |
E |
Get (int index ); |
|
E |
Set (int index, E element) |
|
E |
Remove (int index) |
|
Int |
IndexOf (Object o) |
O position where the first appearance is in the List |
Int |
LastIndexOf (Object o) |
O position of the last appearance in the List |
ListIterator <E> |
ListIterator () |
List iterator |
ListIterator <E> |
ListIterator (int index) |
Obtains the iterator starting from a certain position. index indicates the iterator start position. |
List <E> |
SubList (int fromIndex, int toIndex) |
Sub-List |
The table above shows that an index-related interface is added to perform get, set, and remove operations on the List based on the index. Another type of added interfaces is related to ListIteator, which gets the List iterator.
3.1 ListIterator
Public interface ListIterator <E> extends Iterator <E>
ListIterator not only contains the three interfaces in Iterator, but also adds the interfaces that should be used as a List Iterator, such as next () and previous ().
Modifier and Return Value |
Method Name |
Description |
|
All interfaces in Iterator |
|
Boolean |
HasNext () |
|
E |
Next () |
|
Boolean |
HasPrevious () |
|
E |
Previous () |
|
Int |
NextIndex () |
|
Int |
Previusindex () |
|
Void |
Remove () |
Delete next () returned Elements |
Void |
Set (E) |
Replace the elements returned by next () |
Void |
Add (E) |
Insert an element after nextIndex () |
First, you need to clarify the role of the ListIterator iterator:
Note that the iterator does not have the current element. It has only one cursor concept. The cursor is always between elements, for example:
The initial position of the iterator:
Position of the iterator after calling next ()
Call the previous () cursor to return to the previous position. After traversing the element backward, the cursor will be behind element N.
That is to say, a set with the length of N will have N + 1 cursor position.
3.2 AbstractCollection/AbstractList
The above inheritance graph does not show the existence of AbstractCollect and AbstractList, but these two classes are often encountered when reading the source code. The roles of these two classes are described below.
First, it must be clear that AbstractCollect and AbstractList are both abstract classes rather than interfaces. They implement some functions in the Collection and List interfaces respectively. In this way, the successor directly inherits AbstractXXXX without repeating all the interfaces in the implementation. These two abstract classes are removed from the public part and implemented to reduce the workload of subsequent classes.
Both ArrayList and History List directly or indirectly inherit the AbstartList class. For the inheritance relationships of these two classes:
For details about the interfaces implemented in these two classes, please read the source code without further explanation.
3.3 ArrayList
Public class ArrayList <E> extendsAbstractList <E>
ImplementsList <E>,RandomAccess, Cloneable, java. io. Serializable when we see the definition of ArrayList, we may have a question. Why does it need to implement the List <E> interface after it inherits the AbstractList? The answer is: the List <E> below can be removed. Here, the reader only understands that ArrayList is a List. Finally, it's hard to get to the classes commonly used by developers. It's a bit like: transient Object [] elementData; this very important member variable elementData array is used to store the elements in the ArrayList, when the first element is added, its default length is 10. (The member variables modified by the "transient" keyword in java are not persisted into the file during class serialization, ensuring the security of saving information for this member variable .)
The length of the elementData array can be directly specified in the ArrayList constructor. The question is, how to assign an array of larger length when an array is fully occupied and then an element is added to the ArrayList? How to copy old data to a new array? For the answer, see the source code below.
1 private void grow (int minCapacity) {// minimum required capacity 2 // overflow-conscious code 3 int oldCapacity = elementData. length; 4 int newCapacity = oldCapacity + (oldCapacity> 1); // allocate 1.5 times the minimum capacity 5 if (newCapacity-minCapacity <0) 6 newCapacity = minCapacity; 7 if (newCapacity-MAX_ARRAY_SIZE> 0) 8 newCapacity = hugeCapacity (minCapacity); // compare the maximum capacity (Inter. MAX_VALUE) 9 // minCapacity is usually close to size, so this is a win: 10 elementData = Arrays. copyOf (elementData, newCapacity); // copy the old data to the new array. 11}
Other interfaces are not described in detail.
Reference: https://www.cnblogs.com/bushi/p/6647006.html
Https://www.jianshu.com/p/047e33fdefd2