Abstractlist Source Analysis

Source: Internet
Author: User
Tags addall int size concurrentmodificationexception

Abstractlist provides a skeleton implementation to the list, and its declaration is this:
Public abstract class Abstractlist extends Abstractcollection implements List
Inherits Abstractcollection, implements the list interface.
About Abstractcollection:http://blog.csdn.net/treeroot/archive/2004/09/11/101622.aspx
About List:http://blog.csdn.net/treeroot/archive/2004/09/14/104638.aspx

Let's look at the methods in this class

Public boolean Add (Object o) {
Add (Size (), O);
return true;
}
Direct call to method Add (int index,object o) inserts a data at the end

Abstract public Object get (int index);
This method does not implement

public object Set (int index, Object element) {
throw new Unsupportedoperationexception ();
}
This method is not supported

public void Add (int index, Object element) {
throw new Unsupportedoperationexception ();
}
This method is not supported, and this method directly affects the public boolean add (Object O) method above.

Public Object Remove (int index) {
throw new Unsupportedoperationexception ();
}
This method is not supported

public int indexOf (Object o) {
Listiterator e = Listiterator ();
if (o==null) {
while (E.hasnext ())
if (E.next () ==null)
return E.previousindex ();
} else {
while (E.hasnext ())
if (O.equals (E.next ()))
return E.previousindex ();
}
return-1;
}
This method obtains the index of the specified element in the list, forward search, and finds a minimum value.
If you can't find it, go back to 1 and go through the entire list if you can't find it.

public int LastIndexOf (Object o) {
Listiterator e = listiterator (size ());
if (o==null) {
while (E.hasprevious ())
if (e.previous () ==null)
return E.nextindex ();
} else {
while (E.hasprevious ())
if (O.equals (E.previous ()))
return E.nextindex ();
}
return-1;
}
This method is almost the same as the above, but looking from behind to the front to find the maximum value of an index.

public void Clear () {
RemoveRange (0, size ());
}
Clear all elements between two indexes, including start, not including end, see RemoveRange method.

public boolean addall (int index, Collection c) {
Boolean modified = false;
Iterator E = C.iterator ();
while (E.hasnext ()) {
Add (index++, E.next ());
Modified = true;
}
return modified;
}
This method is implemented by looping through the Add method because each call to the Add method completes the element's back shift, so one needs to move
C.size () time, the efficiency is relatively low. This method is typically overridden in subclasses.

Public iterator iterator () {
return new Itr ();
}
Here is an internal class ITR, see the definition below.

Public Listiterator Listiterator () {
Return Listiterator (0);
}
Returns the default list iterator, starting at the front.

Public Listiterator listiterator (final int index) {
if (index<0 | | index>size ())
throw new Indexoutofboundsexception ("Index:" +index);
return new Listitr (index);

Check the bounds first, as well as an internal class listitr, see the definition below.


The following is the definition of ITR:
About Iterator interface: http://blog.csdn.net/treeroot/archive/2004/09/11/101589.aspx

Private Inner class
Private class Itr implements iterator {
int cursor = 0;
Record cursor Position

int lastret =-1;
The last call to the next () or previous () index, in fact, iterator does not define previous ().

int expectedmodcount = Modcount;
Record the number of changes, modcount in the abstractlist as a structure to change the list number of times.
This is to be followed by a concurrent visit to the iterator and Listiterotor access list, which we'll discuss later.

public Boolean hasnext () {
return cursor!= size ();
}
If the current cursor is not equal to the size of the collection (then a value of 0 to size ()-1) indicates that there is a next value.
The size () is the method in Abstractlist.

Public Object Next () {
try {
Object next = get (cursor);
Checkforcomodification ();
Lastret = cursor++;
return to Next;
catch (Indexoutofboundsexception e) {
Checkforcomodification ();
throw new Nosuchelementexception ();
}
}
What's annoying here is the call to method get (int index) in Abstractlist, where a system exception is caught (can not
Caught exception) indexoutofboundsexception. In any case, throw the concurrency access exception first concurrentmodificationexception
(if any). Normally the current cursor and the last access index all add 1.

public void Remove () {
if (Lastret = = 1)
throw new IllegalStateException ();
Checkforcomodification ();
try {
AbstractList.this.remove (Lastret);
if (Lastret < cursor)
cursor--;
Lastret =-1;
Expectedmodcount = Modcount;
catch (Indexoutofboundsexception e) {
throw new Concurrentmodificationexception ();
}
}
Throws a IllegalStateException exception if the last access index is-1 (as is the case when iterator was just obtained).
Otherwise, the element is deleted, and the cursor value is moved forward before the current cursor. Because the iterator changed the structure of the list,
Here to correct the Expertedmodcount value. Here, if you're going to cross the line when you delete it, it must be somewhere else in the list.
Therefore, a concurrent access exception is thrown. Note: The Lastret is set to-1, and the Remove and listiterator are not invoked at this time
Method of Add,set.
  

final void Checkforcomodification () {
if (Modcount!= expectedmodcount)
throw new Concurrentmodificationexception ();
}
}
If two local records change the same number of times, there are other places to modify this list.

The following is the definition of LISTITR:
About Listiterator Interface: http://blog.csdn.net/treeroot/archive/2004/09/14/104608.aspx

Internal Private class
Private class Listitr extends Itr implements Listiterator {
LISTITR (int index) {
cursor = index;
}
constructor to initialize the current cursor position.

public Boolean hasprevious () {
return cursor!= 0;
}
A current cursor of not 0 indicates an element before it.

Public Object Previous () {
try {
int i = cursor-1;
Object previous = Get (i);
Checkforcomodification ();
Lastret = cursor = i;
return previous;
catch (Indexoutofboundsexception e) {
Checkforcomodification ();
throw new Nosuchelementexception ();
}
}
Returns the previous element of the current cursor, the cursor value and the last access index have changed, and the Concurrency control reference ITR

public int Nextindex () {
return cursor;
}
The index of the next element is equal to the current cursor.

public int Previousindex () {
return cursor-1;
}
Don't say much.

public void set (Object o) {
if (Lastret = 1)
throw new IllegalStateException ()
Checkforcomodification ();      
try {
AbstractList.this.set (Lastret, O);
Expectedmodcount = Modcount;    
} catch (Indexoutofboundsexception e) {
throw new concurrentmodificationexception ();

}
calls the set method of the perimeter class, and concurrency controls the description of the Remove method in the reference ITR.

public void Add (Object o) {
Checkforcomodification ();
try {
AbstractList.this.add (cursor++, O);
Lastret =-1;
Expectedmodcount = Modcount;
catch (Indexoutofboundsexception e) {
throw new Concurrentmodificationexception ();
}
}
Refer to the description of the Remove method in the ITR.
}

The way back to Abstractlist
Public List sublist (int fromindex, int toindex) {
Return (this instanceof randomaccess?)
New Randomaccesssublist (This, Fromindex, Toindex):
New Sublist (This, Fromindex, Toindex));
}
If the list implements the Randomaccess interface, returns a new Randomaccesssublist instance,
Otherwise, a sublist instance is returned, and these two classes are defined later.

public boolean equals (Object o) {
if (o = = this)
return true;
if (!) ( o instanceof List)
return false;

Listiterator e1 = Listiterator ();
Listiterator e2 = ((List) O). Listiterator ();
while (E1.hasnext () && e2.hasnext ()) {
Object O1 = E1.next ();
Object O2 = E2.next ();
if (!) ( O1==null? O2==null:o1.equals (O2))
return false;
}
Return! (E1.hasnext () | | e2.hasnext ());
}
This method is relatively concise, by traversing two lists to compare, only two list elements and order exactly the same.

public int hashcode () {
int hashcode = 1;
Iterator i = iterator ();
while (I.hasnext ()) {
Object obj = I.next ();
Hashcode = 31*hashcode + (obj==null? 0:obj.hashcode ());
}
return hashcode;
}
This algorithm can guarantee that two lists are equal when they are hashcode.

protected void RemoveRange (int fromindex, int toindex) {
Listiterator it = Listiterator (Fromindex);
for (int i=0, N=toindex-fromindex i<n; i++) {
It.next ();
It.remove ();
}
}
This method is inefficient because it deletes the specified element through an iterator, and the iterator calls the Remove method.

protected transient int modcount = 0;
This field represents the number of times the list has been modified to control concurrent access.

Abstractlist's content is over, but we've also used two classes: Randomaccesslist and sublist.
Look at the definition of sublist:
Class Sublist extends Abstractlist {
Private Abstractlist L;
private int offset;
private int size;
private int expectedmodcount;

Sublist (abstractlist list, int fromindex, int toindex) {
if (Fromindex < 0)
throw new Indexoutofboundsexception ("Fromindex =" + Fromindex);
if (Toindex > List.size ())
throw new Indexoutofboundsexception ("Toindex =" + Toindex);
if (Fromindex > Toindex)
throw new IllegalArgumentException ("Fromindex" + Fromindex +
") > Toindex (" + Toindex + "));
L = list;
offset = Fromindex;
size = Toindex-fromindex;
Expectedmodcount = L.modcount;
}

public object Set (int index, Object element) {
Rangecheck (index);
Checkforcomodification ();
Return L.set (index+offset, Element);
}

Public Object get (int index) {
Rangecheck (index);
Checkforcomodification ();
Return L.get (Index+offset);
}

public int size () {
Checkforcomodification ();
return size;
}

public void Add (int index, Object element) {
if (index<0 | | index>size)
throw new Indexoutofboundsexception ();
Checkforcomodification ();
L.add (index+offset, Element);
Expectedmodcount = L.modcount;
size++;
modcount++;
}

Public Object Remove (int index) {
Rangecheck (index);
Checkforcomodification ();
Object result = L.remove (Index+offset);
Expectedmodcount = L.modcount;
size--;
modcount++;
return result;
}

protected void RemoveRange (int fromindex, int toindex) {
Checkforcomodification ();
L.removerange (Fromindex+offset, Toindex+offset);
Expectedmodcount = L.modcount;
Size = (Toindex-fromindex);
modcount++;
}

public boolean AddAll (Collection c) {
Return AddAll (size, c);
}

public boolean addall (int index, Collection c) {
if (index<0 | | index>size)
throw New Indexoutofboundsexception (
"Index:" +index+ ", Size:" +size);
int csize = C.size ();
if (csize==0)
return false;

Checkforcomodification ();
L.addall (Offset+index, C);
Expectedmodcount = L.modcount;
Size + = CSize;
modcount++;
return true;
}

Public iterator iterator () {
return Listiterator ();
}

Public Listiterator listiterator (final int index) {
Checkforcomodification ();
if (index<0 | | index>size)
throw New Indexoutofboundsexception (
"Index:" +index+ ", Size:" +size);

return new Listiterator () {
Private Listiterator i = L.listiterator (Index+offset);
public Boolean hasnext () {
Return Nextindex () < size;
}
Public Object Next () {
if (Hasnext ())
return I.next ();
Else
throw new Nosuchelementexception ();
}
public Boolean hasprevious () {
Return Previousindex () >= 0;
}
Public Object Previous () {
if (hasprevious ())
return i.previous ();
Else
throw new Nosuchelementexception ();
}
public int Nextindex () {
Return I.nextindex ()-offset;
}
public int Previousindex () {
Return I.previousindex ()-offset;
}
public void Remove () {
I.remove ();
Expectedmodcount = L.modcount;
size--;
modcount++;
}
public void set (Object o) {
I.set (o);
}
public void Add (Object o) {
I.add (o);
Expectedmodcount = L.modcount;
size++;
modcount++;
}
};
}

Public List sublist (int fromindex, int toindex) {
Return to New Sublist (this, Fromindex, Toindex);
}

private void Rangecheck (int index) {
if (index<0 | | index>=size)
throw new Indexoutofboundsexception ("Index:" +index+
", Size:" +size);
}

private void Checkforcomodification () {
if (L.modcount!= expectedmodcount)
throw new Concurrentmodificationexception ();
}

This class inherits abstractlist, which is basically well understood, but there are a few things that need to be done mainly:
1. Note the difference between the L.modcount,modcount,expectedmodcount, Modcount is sublist inherited from the domain
Expectedmodcount is sublist to prevent concurrent access to the newly added domain, L.modcount of course good understanding.
The 2.public listiterator listiterator (final int index) method uses an anonymous class.
3. Note that the Sublist constructor has only one, requires three parameters, and sublist is just a view, modifying sublist
It is also equivalent to modifying the list in the parameter.

And finally, Randomaccesssublist.
Class Randomaccesssublist extends sublist implements Randomaccess {
Randomaccesssublist (abstractlist list, int fromindex, int toindex) {
Super (list, Fromindex, toindex);
}

Public List sublist (int fromindex, int toindex) {
Return to New Randomaccesssublist (this, Fromindex, Toindex);
}
}
There is nothing real about this class, but the type is not the same as the sublist (because there is one more Randomaccess interface).


This is just an analysis of the implementation of this class, and does not evaluate the quality of this class design, but I do hate nested classes (especially nesting
Class can also invoke the method of the perimeter class, and the other sublist returns a view, rather than a completely separate list, so it's not good.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.