From: http://www.cnblogs.com/huangfox/archive/2010/10/11/1847863.html
I. shortlist
3.1 create: Sequence List ()
The underlying data structure of the shortlist is a two-way linked list. Since it is a two-way linked list, there must be a Data Structure-we can call it a node. The node instance stores business data, the location information of the previous node and the location information of the next node, as shown in:
Figure -- double-line linked list and Node
First, let's look at the node class:
Private Static classEntry {
E element;
Entry next;
Entry previous;
Entry (E element, entry next, entry previous ){
This. Element = element;
This. Next = next;
This. Previous = previous;
}
}
The node class is very simple. The element stores business data, and the previous and next stores the information of the front and back nodes respectively (we usually call it the pointer of the front and back nodes in the data structure ).
When declaring an external list object, create an entry object, but all are empty.
Private transientEntry header =
NewEntry (Null,Null,
Null);
Private transient intSize = 0;
When executing the constructor, point the previous and next values of the header instance to the header instance.
PublicPipeline list (){
Header. Next = header. Previous = header;
}
After the constructor is executed, the header instance forms a closed loop, as shown in:
Figure -- initialize the consumer list
3.2 add data: add ()
From the source code, we can see that adding data to the linked list starts from the header of the two-way linked list. The Code is as follows:
Public BooleanAdd (E ){
Addbefore (E, header );
Return true;
}
PrivateEntry addbefore (E, entry ){
Entry newentry = new entry (E, entry, entry. Previous );
Newentry. Previous. Next = newentry;
Newentry. Next. Previous = newentry;
Size ++;
Modcount ++;
ReturnNewentry;
}
The following describes how to add the first data:
Step 1: Initialize the consumer list instance:
Figure -- after Initialization
Step 2: initialize a pre-added entry instance (newentry ).
Entry newentry = newentry (E, entry, entry. Previous );
Figure -- create a new node instance
Step 3: Adjust the front and back pointers of newly added nodes and headers.
Newentry. Previous. Next = newentry;
Newentry. Previous is the header, newentry. Previous. Next is the next of the header pointing to the newentry instance. Line 4 points to newentry.
Newentry. Next. Previous = newentry;
Newentry. Next is the header, newentry. Next. Previous is the header's previous pointing to the newentry instance. Line 3 points to newentry.
As shown in figure:
Figure -- merge list after adding the first node
The following describes how to add a second data:
Step 1: Create a node.
Figure -- add a second node
Step 2: Adjust the front and back pointer information of the new node and the header node.
Figure -- Adjust the pointer information before and after
The data added later is the same as the data above. The capacity limit of the consumer list instance is not limited.
3.3 delete data: Remove (), remove (INT), remove (object)
Although there are a variety of data deletion operations (only remove (), remove (INT), and remove (object) are considered here) in the deletelist, the code for actually performing the delete operation is as follows:
PrivateE remove (Entry e ){
If(E = header)
Throw newNosuchelementexception ();
E result = E. element;
E. Previous. Next = E. Next;
E. Next. Previous = E. Previous;
E. Next = E. Previous =
Null;
E. Element =
Null;
Size --;
Modcount ++;
ReturnResult;
}
The parameter received by the Remove Method is a node instance, that is, the pre-deleted node. Except that remove () is the first node to be deleted (the first node after the header node )--
PublicEremovefirst (){
ReturnRemove (Header. Next);
}
Remove (INT) is to delete a node at a specified position --
PrivateEntry entry (IntIndex ){
If(Index <0 | index> = size)
Throw newIndexoutofboundsexception ("index:" + index +
", Size:" + size );
Entry E = header;
If (index <(size> 1) {// determines whether to traverse from the beginning or from the end.
For (INT I = 0; I <= index; I ++)
E = E. Next;
} Else {
For (INT I = size; I> index; I --)
E = E. Previous;
}
ReturnE;
}
Remove (object) is a node that deletes the specified content --
Public BooleanRemove (Object O ){
If(O =Null){
For(Entry E = header. Next; e! = Header; E = E. Next ){
If(E. Element =Null){
Remove (E );
Return true;
}
}
}Else{
For(Entry E = header. Next; e! = Header; E = E. Next ){
If(O. Equals (E. element )){
Remove (E );
Return true;
}
}
}
Return false;
}
Return to our remove (Entry e) method:
Because a node is deleted, the cursor information of the corresponding node is adjusted as follows:
E. Previous. Next = E. Next; // The post pointer of the previous node of the pre-deleted node points to the next node of the pre-deleted node.
E. Next. Previous = E. Previous; // The front pointer of the last node of the pre-deleted node points to the previous node of the pre-deleted node.
Clear pre-deleted nodes:
E. Next = E. Previous = NULL;
E. Element = NULL;
The resource is handed over to GC for recovery and the deletion operation is complete.
Compared with arraylist, the revoke list deletion action does not need to "move" a lot of data, which is more efficient.
3.4 get data: Get (INT)
The implementation of the get (INT) method has already been involved in remove (INT. First, determine whether the location information is valid (greater than or equal to 0, less than the size of the current shard list instance), and traverse to the specific location to obtain the business data (element) of the node and return it.
Note: To improve efficiency, You need to determine whether to traverse from the beginning or from the end based on the obtained position.
PrivateEntry entry (IntIndex ){
If(Index <0 | index> = size)
Throw newIndexoutofboundsexception ("index:" + index +
", Size:" + size );
Entry E = header;
If (index <(size> 1) {// determines whether to traverse from the beginning or from the end.
For (INT I = 0; I <= index; I ++)
E = E. Next;
} Else {
For (INT I = size; I> index; I --)
E = E. Previous;
}
ReturnE;
}
Note: The difference between bit operations and direct Division operations.
3.5 data traversal: iterator ()
After learning about iterator of arraylist, pay attention to the following points:
When the iterator method is called, each time a listitr instance is created, it has an attribute cursor, which acts as a cursor.
Hasnext method of the iterator instance:
Public BooleanHasnext (){
ReturnCursor! = Size ();
}
When the cursor reaches the end, false is returned, indicating that the traversal is complete.
The next method of the iterator instance:
PublicE next (){
Checkforcomodification ();
Try{
Enext = get (cursor );
Lastret = cursor ++;
ReturnNext;
}Catch(Indexoutofboundsexception e ){
Checkforcomodification ();
Throw newNosuchelementexception ();
}
}
Return the content of the node at the current cursor position through the get method, and move the cursor back to a position.
During the traversal process, if an action such as add or delete occurs, concurrentmodificationexception will occur, which is similar to arraylist.
3.6 determine the existence or location
The indexof method for obtaining the location already exists in the remove (object) method, while the existing contains (object) method is mainly called the indexof method, compare the returned location of indexof with-1 to determine whether the specified data exists.
3.7 note
The capacity list has no capacity limit;
The producer list is non-thread-safe;
The sort list is implemented based on a two-way linked list. When the Data Order is irrelevant, The arraylist or sort list should be considered comprehensively from the execution efficiency of each action.