Java-source code analysis

Source: Internet
Author: User
Tags addall

Java-source code analysis

Today, when I checked the source code of the listing list, I encountered a pitfall. When I studied the source code, I found that the shortlist is a linear linked list structure, but when I searched for information in baidu, I analyzed the source code of this part, in all, the linked list is a circular linked list structure .. After a long tangle, I thought I was wrong and finally found the result on Google: Because I saw the source code 1.7, almost all of baidu's products were 1.6. And there is no corresponding description. After 1.7, oracle optimized the linear list and optimized the circular structure in 1.6 to a linear chain table structure. Here, I would like to remind my friends that the version must be checked when you look at the source code. Some cases are minor changes, and some may be greatly changed. This will only make you more confused.

Well, let's get down to the truth. Let's analyze some of the source code of the listing list in Java. (This article focuses on the source code of 1.7)

 

I have been talking about the linked list before the basic structure of the linked list. What is a linked list? As the name suggests, a chain table is the same as a chain. Each chain is connected to the back ring and the front ring. In this way, when we need to find a chain, as long as we can find any link of the chain, we can find the link we need. Let's take a look at a graph and we can understand it very well. In the chain list, we call the chain "ring" Node ", and each node has the same structure. Nodes are connected to each other to form the basic data structure of our shortlist, which is also the core of the shortlist. Let's take a look at the difference between the direct structure of javaslist in jdk1.6 and 1.7. First, let's look at the structure in 1.7 and then compare the structure in 1.6. Do you know where the difference is? With the ring structure removed in 1.7, some changes will naturally occur in the code. Understanding the above structure makes analysis much easier. The constructor of the sort list contains three global parameters. size stores the number of nodes in the current linked list. First is the reference of the first node pointing to the linked list. Last is the reference of the last node pointing to the linked list. The listlist constructor has two methods: one is construction without parameters and the other is construction of the Collection object passed in.
// Nothing is done. It is an empty implement public writable list () {} public writable list (Collection c) {this (); addAll (c);} public boolean addAll (Collection c) {return addAll (size, c);} public boolean addAll (int index, Collection c) {// check whether the input index value is within a reasonable range of checkPositionIndex (index ); // convert the given Collection Object into an Object array Object [] a = c. toArray (); int numNew =. length; // if the array is null, false is returned directly if (numNew = 0) return false; // if the array is not empty Node
 
  
Pred, succ; if (index = size) {// when the constructor calls, index = size = 0 to enter this condition. Succ = null; pred = last;} else {// called when the linked list is not empty. The node Method returns the node object succ = node (index) at the given index location; pred = succ. prev;} // traverses the array and inserts the array Object into the Node. for (Object o: a) {@ SuppressWarnings ("unchecked") E e = (E) o; Node
  
   
NewNode = new Node <> (pred, e, null); if (pred = null) first = newNode; else pred. next = newNode; pred = newNode;} if (succ = null) {last = pred; // assign the last node of the current linked list to last} else {// when the linked list is not empty, connect the disconnected part to pred. next = succ; succ. prev = pred;} // record the number of current nodes size + = numNew; modCount ++; return true ;}
  
 
It should be noted that Node is the internal private class of the consumer list. Its composition is very simple and there is only one constructor.
    private static class Node
 
  
   
     {        E item;        Node
    
      next;        Node
     
       prev;        Node(Node
      
        prev, E element, Node
       
         next) { this.item = element; this.next = next; this.prev = prev; } }
       
      
     
    
   
  
 
The Parameter order of the constructor method is: reference of the successor node, data, and reference of the successor node. With the above description, let's look at the constructor of the listing list.
This code is quite understandable. We can use images for further understanding. This code is divided into two cases: the original linked list is empty, and the original linked list has values. Let's look at the original value.
In combination with the code, is the idea much clearer? If the linked list is empty, it is better to directly convert the imported Collection object into an array. The first value of the array is used as the header node, that is, head, add the following order to the column. In addition, this reduces the number of operations that change the original node's point. The following two constructor methods can be summarized as follows: The parameter-free construction is empty. Input Collection object with parameters, convert the object into an array, and connect the first and end of the array in the traversal order. The global variables first and last point to the first and last of the linked list respectively.AddFirst/addLast
Public void addFirst (E e) {linkFirst (e);} private void linkFirst (E e) {final Node
        
         
F = first; final Node
         
          
NewNode = new Node <> (null, e, f); // create a new Node. The new Node then points to the original header Node, which moves the original header Node to the back, the position of the new node instead of the header node. First = newNode; if (f = null) last = newNode; else f. prev = newNode; size ++; modCount ++ ;}
         
        
In fact, as long as you understand the above data structure, this code is well understood. Add a new node to the head of the current linked list. If the method name is used, add a node to the head of the current linked list. Since it is a head node, the front of the head node must be null, so this is also the Node NewNode = new Node <> (null, e, f. Next, point first to the header node of the current linked list, and then judge the previous header node. If the header node is null before the element is inserted, the element currently added is the first point, that is, the header node. Therefore, the current situation is: the header node = the newly added node = the end node. If the header node is not null before the element is inserted, it proves that the previous linked list has a value. Then we only need to point the new node to the original header node, the last node does not change. In this way, the original header node becomes the second node. We achieved our goal.
The implementation of the addLast method is the same as that of addFirst, which is not described here. If you are interested, you can check the source code. In fact, the methods of the add series in the shortlist are all similar. They all create new nodes and change the pointing relationship of the previous nodes. That's all. GetFirst/getLast Method Analysis
    public E getFirst() {        final Node
           
             f = first;        if (f == null)            throw new NoSuchElementException();        return f.item;    }    public E getLast() {        final Node
            
              l = last;        if (l == null)            throw new NoSuchElementException();        return l.item;    }
            
           
This Code does not need to be parsed .. Very simple. Get Method Analysis: here we mainly look at the node method it calls.
Public E get (int index) {// check whether the specified index value is within a reasonable range; return node (index). item;} Node
             
              
Node (int index) {if (index <(size> 1) {Node
              
               
X = first; for (int I = 0; I <index; I ++) x = x. next; return x;} else {Node
               
                
X = last; for (int I = size-1; I> index; I --) x = x. prev; return x ;}}
               
              
             
At the beginning, I was puzzled. Why? Later, I realized that what the code should do is: Determine the given index value. If the index value is half the length of the entire linked list, find it from the back, if the index value is less than the length of the entire linked list, you can find it from the beginning to the end. In this way, no matter how long the linked list is, you can search for at most half of the length of the linked list, which greatly improves the efficiency.
RemoveFirst/removeLast Method Analysis
    public E removeFirst() {        final Node
                
                  f = first;        if (f == null)            throw new NoSuchElementException();        return unlinkFirst(f);    }    private E unlinkFirst(Node
                 
                   f) {        // assert f == first && f != null;        final E element = f.item;        final Node
                  
                    next = f.next;        f.item = null;        f.next = null; // help GC        first = next;        if (next == null)            last = null;        else            next.prev = null;        size--;        modCount++;        return element;    }
                  
                 
                
Remove the header node, change the original second node to the header node, and change the direction of the frist. If there is only one node left, all nodes are removed and set to null. For other methods of listing, the above methods are basically packaged, with no major changes.

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.