LinkedList 소스 코드 분석 One

1 LinkedList 소개

여기에 사진 설명 삽입

1 LinkedList는 AbstractSequentialList를 상속하고 List 인터페이스를 구현합니다. 이중 연결 목록의 실현입니다.
2 LinkedList는 Deque 인터페이스를 구현합니다. 데크가 구현되었음을 나타냅니다. FIFO가 될 수 있습니다. LIFO (후입 선출)도 가능합니다
.3 LinkedList는 복제 가능함을 나타내는 Cloneable 및 Serializable 인터페이스를 구현합니다. 직렬화 할 수도 있습니다.

2 부동산 소개

/**
 * 元素的个数
 */
transient int size = 0;

/**
 * 指向第一个结点的指针
 */
transient Node<E> first;

/**
 * 指向最后一个结点的指针
 */
transient Node<E> last;

3 구조

	//默认的构造器
	public LinkedList() {
    
    
	}

    /**
     * 构造一个包含元素的集合。
     */
    public LinkedList(Collection<? extends E> c) {
    
    
        this();
        addAll(c);
    }

4 연결된 목록 노드 클래스 구조

private static class Node<E> {
    
    
		//数据元素
        E item;
        //后继结点
        Node<E> next;
        //前驱结点
        Node<E> prev;
        

        Node(Node<E> prev, E element, Node<E> next) {
    
    
            this.item = element;
            this.next = next;
            this.prev = prev;
        }
    }

여기에 사진 설명 삽입

5 소스 코드 해석

5.1 E getFirst () 첫 번째 요소 가져 오기

   /**
   * 获取第一个元素。直接将头指针赋值给当前结点,然后当前结点返回存储的数据item。如果为空,则报NoSuchElementException异常。
   */
   public E getFirst() {
    
    
        final Node<E> f = first;
        if (f == null)
            throw new NoSuchElementException();
        return f.item;
    }

5.2 E getLast () 마지막 요소 가져 오기

 /**
   * 获取最后一个元素。直接将尾指针赋值给当前结点,然后当前结点返回存储的数据item。如果为空,则报NoSuchElementException异常。
   */
public E getLast() {
    
    
        final Node<E> l = last;
        if (l == null)
            throw new NoSuchElementException();
        return l.item;
}

5.3 E removeFirst () 첫 번째 요소 삭제

 /**
   * 删除第一个元素。直接将头指针赋值给当前结点,然后解除结点之间的联系。调用unlinkFirst()方法接触引用
   */
public E removeFirst() {
    
    
        final Node<E> f = first;
        if (f == null)
            throw new NoSuchElementException();
        return unlinkFirst(f);
}

unlinkFirst () 메서드를 살펴 보겠습니다.

private E unlinkFirst(Node<E> f) {
    
    
        // 获取删除结点的数据,作为最后的返回
        final E element = f.item;
        //获取删除结点的下一个结点
        final Node<E> next = f.next;
        //将删除结点的数据和后继设置为null,有利于垃圾回收
        f.item = null;
        f.next = null; // help GC
        //将删除结点的后继设置为头结点。
        first = next;
        //设置前驱为空。然后元素个数-1
        if (next == null)
            last = null;
        else
            next.prev = null;
        size--;
        //集合修改的次数。在迭代器迭代集合的时候使用
        modCount++;
        return element;
    }

5.4 E removeLast ()는 마지막 요소를 삭제합니다.

 public E removeLast() {
    
    
 		//将尾结点赋值给当前结点,然后解除尾结点的引用。
        final Node<E> l = last;
        if (l == null)
            throw new NoSuchElementException();
        return unlinkLast(l);
    }

unlinkLast를 호출하여 끝 노드 간의 참조를 해제합니다. 이 메서드의 구현을 살펴 보겠습니다.

private E unlinkLast(Node<E> l) {
    
    
        final E element = l.item;
        //获取删除结点的前驱
        final Node<E> prev = l.prev;
        l.item = null;
        l.prev = null; // 方法GC
        //将前驱设置为尾结点
        last = prev;
        if (prev == null)
            first = null;
        else
            prev.next = null;
        size--;
        modCount++;
        return element;
    }

5.5 addFirst (E e), addLast (E e) 요소 추가

//头插
public void addFirst(E e) {
    
    
        linkFirst(e);
}
//尾插
public void addLast(E e) {
    
    
        linkLast(e);
}

달성하려면 linkFirst 및 linkLast를 각각 호출하십시오. 이 두 가지 방법을 살펴 보겠습니다.

 private void linkFirst(E e) {
    
    
 		//获取头结点
        final Node<E> f = first;
        //创建结点。设置前驱为null。后继为f。也就是插入之前的头结点
        final Node<E> newNode = new Node<>(null, e, f);
        //将创建的新节点赋值给头结点。
        first = newNode;
        if (f == null)
        	//如果当前结点为空,那么新结点就是尾结点。
            last = newNode;
        else
        	//将新节点设置为当前结点的前驱
            f.prev = newNode;
        //元素个数+1
        size++;
        modCount++;
    }

    /**
     * Links e as last element.
     */
    void linkLast(E e) {
    
    
    	//获取尾结点
        final Node<E> l = last;
        //创建新结点。前驱为插入之前的尾结点。后继为空
        final Node<E> newNode = new Node<>(l, e, null);
        //新结点设置为尾结点
        last = newNode;
        if (l == null)
            first = newNode;
        else
        	//设置新节点为插入之前的后继结点
            l.next = newNode;
        size++;
        modCount++;
    }

5.6 boolean contains (Object o) 요소 포함 여부 결정

public boolean contains(Object o) {
    
    
        return indexOf(o) >= 0;
    }

달성하려면 indexOf () 메서드를 호출합니다. 내부 방법을 살펴 보겠습니다.

public int indexOf(Object o) {
    
    
        int index = 0;
        if (o == null) {
    
    
        	//遍历链表。如果当前对象为空,返回索引。
            for (Node<E> x = first; x != null; x = x.next) {
    
    
                if (x.item == null)
                    return index;
                index++;
            }
        } else {
    
    
        	//遍历链表。如果当前对象equals结点元素,返回索引。
            for (Node<E> x = first; x != null; x = x.next) {
    
    
                if (o.equals(x.item))
                    return index;
                index++;
            }
        }
        return -1;
    }

5.7 int size () 연결 목록의 길이 가져 오기

public int size() {
    
    
        return size;
}

5.8 부울 add (E e) 요소 추가

기본값은 테일 플러그입니다.

public boolean add(E e) {
    
    
        linkLast(e);
        return true;
    }

5.9 부울 remove (Object o) 요소 삭제

public boolean remove(Object o) {
    
    
		//元素为空的情况
        if (o == null) {
    
    
            for (Node<E> x = first; x != null; x = x.next) {
    
    
                if (x.item == null) {
    
    
                    unlink(x);
                    return true;
                }
            }
        } else {
    
    
        //元素不为空的情况
        //遍历链表,找到元素,然后解除链表结点之间的引用。调用了unlink来解除
            for (Node<E> x = first; x != null; x = x.next) {
    
    
                if (o.equals(x.item)) {
    
    
                    unlink(x);
                    return true;
                }
            }
        }
        return false;
    }

unlink 메서드는 요소 간의 참조를 제거합니다. 이 방법을 살펴보십시오.

E unlink(Node<E> x) {
    
    
        // assert x != null;
        final E element = x.item;
        //获取当前删除结点的后继和前驱
        final Node<E> next = x.next;
        final Node<E> prev = x.prev;
		//前驱为空,说明是头结点。那么直接将该结点的后继结点设置为头结点
        if (prev == null) {
    
    
            first = next;
        } else {
    
    
        //将当前删除结点的后继结点设置为当前删除结点的后继结点。
            prev.next = next;
            //并且将当前结点的前驱结点设置为空。
            x.prev = null;
        }
		//后继结点为空,表示为尾结点
        if (next == null) {
    
    
        	//设置前驱为尾结点
            last = prev;
        } else {
    
    
        	//后继结点不为空。将删除元素的前驱设置为后继结点的前驱。后继结点设置为空
            next.prev = prev;
            x.next = null;
        }

        x.item = null;
        //元素个数-1
        size--;
        modCount++;
        return element;
    }

5.10 clear ()는 컬렉션을 지 웁니다.

각 노드를 탐색 한 다음 모든 노드 요소를 비어 있도록 설정합니다. 노드를 비워 두십시오. 컬렉션 요소의 수가 0으로 설정되었습니다.

public void clear() {
    
    
        for (Node<E> x = first; x != null; ) {
    
    
            Node<E> next = x.next;
            x.item = null;
            x.next = null;
            x.prev = null;
            x = next;
        }
        first = last = null;
        size = 0;
        modCount++;
    }

추천

출처blog.csdn.net/GoSaint/article/details/113923994