Three major data structures linked lists, trees and graphs, sequential table as one of the, can be said to be the longest use of programming in peacetime.
The list interface is an implementation of the sequential table in Java. It has very many sub-interfaces and implementation classes, which are very convenient to use in normal programming. But further, it is necessary for us to understand the fact and principle, and to compare with the data structure, and to use in the normal programming, to write efficient code.
First of all, look at the hierarchical relationship of the list interface, I draw according to the class structure of the JDK simple:
As can be seen, the list interface is derived from the collection interface. So first understand the next collection interface.
Collection
Collection is the root of the collection frame. He defines general behavior for collection operations such as adding elements, bulk joins, deletions, bulk deletions, collection sizes, including, iterators, and so on. Its interface definition is no longer posted here. In relation, collection is inherited from the Iterable interface, which has only one method:
Public interface Iterable<t> { /** * Returns a {@link Iterator} for the elements of this object. * * @return an {@code Iterator} instance. * /iterator<t> Iterator ();}
Among iterator such as the following:
Public interface Iterator<e> {public boolean hasnext (); Public E next (); public void Remove ();
Abstractcollection
Abstractcollection is an abstract implementation of the collection interface, which implements most of the functions. As seen below, we can implement our own collection by simply implementing three methods:
collection<string> C = /** * * self-defined Implementation Demo sample, in the implementation of some methods in abstractcollection, such as clear. The *iterator () method is called, whereas in these methods in subclasses, implementation is typical of the template pattern. * * * * New abstractcollection<string> () {/* * * iterator */ @Override Public Iterator<string> Iterator () { //TODO auto-generated method stub return null; } /* * Size * /@Override public int size () { //TODO auto-generated method stub return 0; The abstract implementation is throwing an exception. We need to implement it ourselves . */@Override public boolean Add (String e) { return true; } };
For example, the following snippet from Abstractcollection, called the iterator method, has a lot of similar code, such as AddAll, RemoveAll, contains, ToArray (), and so on, these implementations are just the main implementations, A subclass that is more efficient will overwrite it. Typically visible behind the ArrayList of the ToArray ().
public void Clear () { iterator<e> E = Iterator (); while (E.hasnext ()) { e.next (); E.remove (); } }
List
The list interface represents the linked list in the data structure, which inherits the collection interface. Added a number of linked list operations, mainly random access, delete, find, dedicated iterators, etc., as seen below:
/** Random get */e get (int index); /** * Random Set value * /E Set (int index, e element); /** * * * randomly added * /void Add (int index, E element); /** * Random removal of * /E Remove (int index); Search Operations /** * Find * * * int indexOf (Object o); /** * Search from after * /int lastIndexOf (Object o); List iterators /** * Dedicated iteration * /listiterator<e> listiterator (); /** * Iterate from a location * /listiterator<e> listiterator (int index); View /** * sub-list * /list<e> sublist (int fromIndex, int toindex);
Abstractlist
This is an abstract implementation of the list interface, similar to Abstractcollection, which implements the main function and defers the critical approach to the subclass. For example, one of the following schematic subclasses is seen:
list<string> l =/** * * Demo Sample Implementation */New Abstractlist<stri Ng> () {/* * * random get */@Override public String get (int index) { return null; }/* * size */@Override public int size () {return 0; }/* * The implementation throws an exception in the superclass. Indicates that the immutable list * * becomes variable after its own implementation/@Override public String Set (int index, STR ing element) {return null; }/* * Default implementation throws Exception */@Override public void Add (int index, String element) {}/** * default implementation throws an exception */@Overr IDE public String Remove (int index) {return null; } };
Listiterator
The list interface adds a new method, one of which is to return listiterator, which expands the iterator. Added method for forward traversal.
The main list is ordered.
In fact, we don't say much. It is important to note that the iterator invalidation problem is in the list implementation. A field Modcountis maintained, and this value changes when the list is changed, such as Add/remove. When an iterator is constructed, this value retains a copy in the iterator, and the methods in the iterator are used to check that the Modcount in the replica and list are consistent, assuming inconsistencies and throwing an iterator exception.
It is important to note that the for each syntax in Java. After compiling, it is the iterator that is used.
For example, the following part of the source Code demo sample:
Private class Itr implements Iterator<e> { /** This class is an internal class. Direct access to abstractlist fields * Index of element to being returned by subsequent call to next. */ int cursor = 0; /** * Index of element returned by most recent call to Next or * Previous. Reset To-1 If this element was deleted by a call * to remove. * /int lastret =-1; /** * Note this */ int expectedmodcount = Modcount; /** * Iterator Next method */public E next () {/** * before operation check * /checkforcomodification (); try { E next = get (cursor); Lastret = cursor++; return next; } catch (Indexoutofboundsexception e) { checkforcomodification (); throw new Nosuchelementexception (); } } /** * Check for iterator invalidation issues. */ final void Checkforcomodification () { if (modcount! = expectedmodcount) throw new Concurrentmodificationexception (); } }
ArrayList
This is the longest used data structure in general programming, based on the sequential table of array implementations. However, arrays can be expanded on their own initiative. It inherits directly from Abstractlist, so it only studies its key realization and method.
Array storage
ArrayList is an array-based store. The default construction initial size is 10, and we will see that this initial size will affect its performance to some extent:
/** * The array buffer into which the elements of the ArrayList is stored. * The capacity of the ArrayList is the length of this array buffer. */private transient object[] elementdata;public ArrayList (int initialcapacity) { super (); if (initialcapacity < 0) throw new IllegalArgumentException ("Illegal capacity:" + initialcapacity); This.elementdata = new object[initialcapacity]; } /** * Constructs an empty list with an initial capacity of ten. * /Public ArrayList () {This (ten); }
Add method
The list interface has an overloaded method of two Add. The first is to add an element at the end of the list, the second is to add the element randomly, and its own way of expanding the data capacity is ensurecapacity (int), which guarantees the size:
/** * This method is already implemented in the parent class. But Arralylist covered the fact now. Implemented with more efficient implementations */public boolean Add (E e) {ensurecapacity (size + 1); Increments modcount!! elementdata[size++] = e; return true; }/** * Add elements anywhere. The corresponding element moves back, preserving the characteristics of the list. * The system.arraycopy efficiency is high. * */public void Add (int index, E element) {if (Index > Size | | Index < 0) throw new Indexoutofboundsexception ("Index:" +index+ ", Size:" +size); Ensurecapacity (size+1); Increments modcount!! System.arraycopy (Elementdata, index, Elementdata, index + 1, size-index); Elementdata[index] = element; size++; }/** * Guarantees the size of list lists. If the assumption is insufficient, enlarge.* This method consumes more performance. Therefore, assuming that the implementation can know or estimate the size of the ayyaylist, the * can set the appropriate initial capacity at the time of construction. */public void ensurecapacity (int mincapacity) {modcount++; Gets the old array size int oldcapacity = elementdata.length; The comparison, assuming insufficient is the expansion if (Mincapacity > Oldcapacity) {Object olddata[] = elementdata; int newcapacity = (oldcapacity * 3)/2 + 1; if (Newcapacity < mincapacity) newcapacity = mincapacity; Call efficient Arraycopy Elementdata = arrays.copyof (Elementdata, newcapacity); } }
Vector
Implementation and Arraaylist are basically consistent. Just add a synchronous operation to the method, but be aware that its thread safety is relative, such as a thread to add operation, another line Cheng, will definitely be out of the ordinary.
There is also a stack that inherits vectors. Added a stack of related methods. such as push, and pop.
LinkedList
List-based sequential table. Compared with ArrayList. Its random insertion and deletion is more efficient. Because it does not need to expand and move element operations. But random access is less efficient (random access requires traversal from the head node).
Abstractsequentiallist
LinkedList its inheritance in abstractsequentiallist. In the abstractsequentiallist, the abstract method in Abstractlist is realized. Are all based on iterators, which at the same time override methods that return iterators as abstract methods. Therefore, the key to realize LinkedList is the iterator. For example, see the following:
Public abstract class Abstractsequentiallist<e> extends Abstractlist<e> {/** * Iterator implementation-based get */Public E get (int index) {try {return Listiterator (index). Next (); } catch (Nosuchelementexception exc) {throw new Indexoutofboundsexception ("Index:" +index); }}/** * Set based on iterator implementation */public E set (int index, e element) {try {listiterator<e> E = l Istiterator (index); E oldval = E.next (); E.set (Element); return oldval; } catch (Nosuchelementexception exc) {throw new Indexoutofboundsexception ("Index:" +index); }/* The add */public void Add (int index, E Element) based on the iterator implementation {try {Listiterator (index). Add (Element); } catch (Nosuchelementexception exc) {throw new Indexoutofboundsexception ("Index:" +index); }}/** * Based on the iterator implementation of remove * */public E remove (int index) {try {listiterator<e>E = listiterator (index); E outcast = E.next (); E.remove (); return outcast; } catch (Nosuchelementexception exc) {throw new Indexoutofboundsexception ("Index:" +index); }} public iterator<e> Iterator () {return listiterator (); }/** * Returns a list iterator over the elements in this list (in proper * sequence). * */Public abstract listiterator<e> listiterator (int index);}
LinkedList
LinkedList In addition to the implementation of the list interface, but also implemented a queue of related interfaces, this is not mentioned here. By the Listiterator interface, it is known that LinkedList is also a sequential table that can be traversed in two directions.
It is only necessary to study the structure and iterator implementation of each linked list node.
A linked list node, as seen below, is a static inner class:
private static class Entry<e> { E element; Entry<e> Next; Entry<e> previous; Entry (E element, entry<e> Next, entry<e> previous) { this.element = element; This.next = Next; this.previous = previous; } }
Its iterator implementation is an inner class. Next, with its add operation description, the others are similar:
Private class Listitr implements listiterator<e> {private entry<e> lastreturned = header; Private entry<e> Next; private int nextindex; private int expectedmodcount = Modcount; /** * Constructed using an optimization technique, depending on whether the index decides to traverse from before or after. */listitr (int index) {if (Index < 0 | | index > size) throw New in Dexoutofboundsexception ("Index:" +index+ ", Size:" +size); if (Index < (size >> 1)) {next = Header.next; for (nextindex=0; nextindex<index; nextindex++) next = Next.next; } else {next = header; for (nextindex=size; nextindex>index; nextindex--) next = next.previous; }/* * list is inserted, when constructing this iterator, index is the location of the insertion, so the directly inserted element can be * * addbefor is an array List method, that is, the link list insertion, the pointer changes the process, here do not repeat. */public void Add (e e) {checkforcomodification (); lastreturned = header; Addbefore (E, next); nextindex++; expectedmodcount++; } final void Checkforcomodification () { if (modcount! = expectedmodcount) throw new Concurrentmodificationexception (); }}/** *abstractsequentiallist method, randomly inserted.
First, construct an iterator starting with index */public void Add (int index, E element) {try {listiterator (Inde x). Add (Element); } catch (Nosuchelementexception exc) {throw new Indexoutofboundsexception ("Index:" +index); } }
Copyonwritearraylist
Copyonwritearraylist is a tool class in Java and contracted, and is introduced in jdk1.5, and its content is sufficient to write an article, so it is no longer open. Just a brief description of it.
Its basic idea can be seen from the name, when the writing operation. A copy is copied and the write is made to the copy.
The read and traverse operations occur on the replica that exists at the moment the operation occurs.
Write operations when the shackles. No lock is added when reading the operation. And through the semantics of the Java memory model, elegant design.
Copyonwrite concurrent containers are used for read-write-less concurrency scenarios. The Copyonwrite container only ensures that the data is finally consistent. There is no guarantee of real-time data consistency. So suppose you want to write the data. can read it immediately. Please do not use the Copyonwrite container.
Detailed can take a look at the article:
Talk about Copy-on-write containers in concurrent-java
Java memory Model Happens-before vulgar solution
A brief analysis of Java list source code