国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Java進(jìn)階(7)——手動(dòng)實(shí)現(xiàn)LinkedList & 內(nèi)部node類(lèi)的實(shí)現(xiàn) & 增刪改查的實(shí)現(xiàn) & toString方法 & 源碼的初步理解

這篇具有很好參考價(jià)值的文章主要介紹了Java進(jìn)階(7)——手動(dòng)實(shí)現(xiàn)LinkedList & 內(nèi)部node類(lèi)的實(shí)現(xiàn) & 增刪改查的實(shí)現(xiàn) & toString方法 & 源碼的初步理解。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

引出


1.linkedList的節(jié)點(diǎn),當(dāng)前,上一個(gè),下一個(gè)的思想;
2.根據(jù)index找node的方法,根據(jù)index確定從頭部還是尾部;
3.linkedlist的增刪改查的實(shí)現(xiàn),本質(zhì)是改變節(jié)點(diǎn)的信息;
4.遞歸方法實(shí)現(xiàn)自定義鏈表的toString方法;文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-668374.html

從ArrayList到Linkedlist

Java進(jìn)階(7)——手動(dòng)實(shí)現(xiàn)LinkedList & 內(nèi)部node類(lèi)的實(shí)現(xiàn) & 增刪改查的實(shí)現(xiàn) & toString方法 & 源碼的初步理解,Java,java,開(kāi)發(fā)語(yǔ)言

手動(dòng)實(shí)現(xiàn)ArrayList

Java進(jìn)階(3)——手動(dòng)實(shí)現(xiàn)ArrayList & 源碼的初步理解分析 & 數(shù)組插入數(shù)據(jù)和刪除數(shù)據(jù)的問(wèn)題

Java進(jìn)階(7)——手動(dòng)實(shí)現(xiàn)LinkedList & 內(nèi)部node類(lèi)的實(shí)現(xiàn) & 增刪改查的實(shí)現(xiàn) & toString方法 & 源碼的初步理解,Java,java,開(kāi)發(fā)語(yǔ)言

從ArrayList到LinkedList

如果發(fā)生對(duì)表的一些插入和刪除操作,特別是對(duì)表的前端進(jìn)行,那么數(shù)組就不是一種好的選擇。另一種數(shù)據(jù)結(jié)構(gòu):鏈表(linked list)。

Java進(jìn)階(7)——手動(dòng)實(shí)現(xiàn)LinkedList & 內(nèi)部node類(lèi)的實(shí)現(xiàn) & 增刪改查的實(shí)現(xiàn) & toString方法 & 源碼的初步理解,Java,java,開(kāi)發(fā)語(yǔ)言

鏈表由一系列節(jié)點(diǎn)組成,這些節(jié)點(diǎn)不必在內(nèi)存中相連。每一個(gè)節(jié)點(diǎn)均含有表元素和到包含該元素后繼元的節(jié)點(diǎn)的鏈(link)。我們稱(chēng)之為next鏈。最后一個(gè)單元的next鏈引用null。

Java進(jìn)階(7)——手動(dòng)實(shí)現(xiàn)LinkedList & 內(nèi)部node類(lèi)的實(shí)現(xiàn) & 增刪改查的實(shí)現(xiàn) & toString方法 & 源碼的初步理解,Java,java,開(kāi)發(fā)語(yǔ)言

鏈表的插入

Java進(jìn)階(7)——手動(dòng)實(shí)現(xiàn)LinkedList & 內(nèi)部node類(lèi)的實(shí)現(xiàn) & 增刪改查的實(shí)現(xiàn) & toString方法 & 源碼的初步理解,Java,java,開(kāi)發(fā)語(yǔ)言

讓每一個(gè)節(jié)點(diǎn)持有一個(gè)指向它在表中的前驅(qū)節(jié)點(diǎn)的鏈,我們稱(chēng)之為雙鏈表(doubly linked list)。

Java進(jìn)階(7)——手動(dòng)實(shí)現(xiàn)LinkedList & 內(nèi)部node類(lèi)的實(shí)現(xiàn) & 增刪改查的實(shí)現(xiàn) & toString方法 & 源碼的初步理解,Java,java,開(kāi)發(fā)語(yǔ)言

總體設(shè)計(jì)

Java進(jìn)階(7)——手動(dòng)實(shí)現(xiàn)LinkedList & 內(nèi)部node類(lèi)的實(shí)現(xiàn) & 增刪改查的實(shí)現(xiàn) & toString方法 & 源碼的初步理解,Java,java,開(kāi)發(fā)語(yǔ)言

在考慮設(shè)計(jì)方面,我們將需要提供三個(gè)類(lèi):
1.MyLinkedList類(lèi)本身,它包含到兩端的鏈、表的大小以及一些方法。
2.Noe類(lèi),它可能是一個(gè)私有的嵌套類(lèi)。一個(gè)節(jié)點(diǎn)包含數(shù)據(jù)以及到前一個(gè)節(jié)點(diǎn)的鏈和到下一個(gè)節(jié)點(diǎn)的鏈,還有一些適當(dāng)?shù)臉?gòu)造方法。
3.LinkedListIterator類(lèi),該類(lèi)抽象了位置的概念,是一個(gè)私有類(lèi),并實(shí)現(xiàn)接口Iterator。它提供了方法next、hasNext和remove的實(shí)現(xiàn)。

標(biāo)記節(jié)點(diǎn):

前端創(chuàng)建一個(gè)額外的節(jié)點(diǎn),邏輯上代表開(kāi)始的標(biāo)記。這些額外的節(jié)點(diǎn)有時(shí)候就叫作標(biāo)記節(jié)點(diǎn)(sentinel node);特別地,在前端的節(jié)點(diǎn)有時(shí)候也叫作頭節(jié)點(diǎn)(header node),而在末端的節(jié)點(diǎn)有時(shí)候也叫作尾節(jié)點(diǎn)(tail node)

Java進(jìn)階(7)——手動(dòng)實(shí)現(xiàn)LinkedList & 內(nèi)部node類(lèi)的實(shí)現(xiàn) & 增刪改查的實(shí)現(xiàn) & toString方法 & 源碼的初步理解,Java,java,開(kāi)發(fā)語(yǔ)言

Node類(lèi)

私有的內(nèi)部類(lèi)

  • 當(dāng)前節(jié)點(diǎn),前置節(jié)點(diǎn),后續(xù)節(jié)點(diǎn);
  • 表示鏈表中的一個(gè)基本元素;

Java進(jìn)階(7)——手動(dòng)實(shí)現(xiàn)LinkedList & 內(nèi)部node類(lèi)的實(shí)現(xiàn) & 增刪改查的實(shí)現(xiàn) & toString方法 & 源碼的初步理解,Java,java,開(kāi)發(fā)語(yǔ)言

/**
     * 內(nèi)部類(lèi),節(jié)點(diǎn);屬性,當(dāng)前節(jié)點(diǎn),前置節(jié)點(diǎn),后續(xù)節(jié)點(diǎn)
     * @param <T>
     */
    private static class Node<T> {
        T item; // 當(dāng)前的節(jié)點(diǎn)
        Node<T> next; // 下一個(gè)節(jié)點(diǎn)
        Node<T> prev; // 前置節(jié)點(diǎn)

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

        @Override
        public String toString() {
            String nextStr = null;
            if (next!=null){
                nextStr = next.item.toString();
            }
            String prevStr = null;
            if (prev!=null){
                prevStr = prev.item.toString();
            }

            return "Node{" +
                    " prev=" + prevStr +
                    ",item=" + item +
                    ", next=" + nextStr +
                    '}';
        }
    }

Java進(jìn)階(7)——手動(dòng)實(shí)現(xiàn)LinkedList & 內(nèi)部node類(lèi)的實(shí)現(xiàn) & 增刪改查的實(shí)現(xiàn) & toString方法 & 源碼的初步理解,Java,java,開(kāi)發(fā)語(yǔ)言

Node的方法:根據(jù)index找node

思路:從頭部開(kāi)始找,進(jìn)行循環(huán)

    public Node<T> NodeByIndex(int index){
        Node<T> x = first; // 從頭部開(kāi)始找
        for (int i = 0; i<index;i++){
            x = x.next;
        }
        return x;
    }

源碼采用如下策略

  • 1.根據(jù)index和list的size確定從頭部還是尾部找;
  • 2.根據(jù)index找node節(jié)點(diǎn);

Java進(jìn)階(7)——手動(dòng)實(shí)現(xiàn)LinkedList & 內(nèi)部node類(lèi)的實(shí)現(xiàn) & 增刪改查的實(shí)現(xiàn) & toString方法 & 源碼的初步理解,Java,java,開(kāi)發(fā)語(yǔ)言

分析:

降低了復(fù)雜度:

如果都從頭部找,時(shí)間復(fù)雜度就是O(i),在最極端的情況下,根據(jù)index找最后一個(gè),時(shí)間復(fù)雜度是O(N);

如果是先確定從頭部找,還是從尾部找,則時(shí)間復(fù)雜度最大是O(N/2);

增刪改查的實(shí)現(xiàn)

增加元素

最簡(jiǎn)單的情況,都是從尾部新增元素

  • 1.新的節(jié)點(diǎn)的上一個(gè)節(jié)點(diǎn)為之前的尾部節(jié)點(diǎn);
  • 2.新的尾部節(jié)點(diǎn)為當(dāng)前新增的節(jié)點(diǎn);
  • 3.如果是第一個(gè)節(jié)點(diǎn),則需要把first設(shè)置為當(dāng)前的節(jié)點(diǎn)
  • 4.鏈表的size+1;

Java進(jìn)階(7)——手動(dòng)實(shí)現(xiàn)LinkedList & 內(nèi)部node類(lèi)的實(shí)現(xiàn) & 增刪改查的實(shí)現(xiàn) & toString方法 & 源碼的初步理解,Java,java,開(kāi)發(fā)語(yǔ)言

    @Override
    public void add(T e) {
        Node<T> l = last;
        Node<T> newNode = new Node<>(l, e, null); // 新增的節(jié)點(diǎn),尾部添加

        last = newNode;
        if (l==null){
            // 是第一個(gè)節(jié)點(diǎn)
            first = newNode;
            System.out.println("FirstNode --->"+first);
        }else {
            l.next = newNode;
            System.out.println("Add {"+e+"} ---->"+l);
        }
        size++;
    }

更一般的情況如下,插入一個(gè)元素

Java進(jìn)階(7)——手動(dòng)實(shí)現(xiàn)LinkedList & 內(nèi)部node類(lèi)的實(shí)現(xiàn) & 增刪改查的實(shí)現(xiàn) & toString方法 & 源碼的初步理解,Java,java,開(kāi)發(fā)語(yǔ)言

刪除元素

刪除頭部?尾部?中間

  • 1.如果刪除的是頭部節(jié)點(diǎn),則讓被刪除的節(jié)點(diǎn)的下一個(gè)節(jié)點(diǎn)為first節(jié)點(diǎn);
  • 2.如果刪除的尾部節(jié)點(diǎn),則讓被刪除的節(jié)點(diǎn)的上一個(gè)節(jié)點(diǎn)的下一個(gè)節(jié)點(diǎn)為null;
  • 3.如果刪除的是中間的節(jié)點(diǎn),讓該節(jié)點(diǎn)的前置節(jié)點(diǎn)的下一個(gè)節(jié)點(diǎn)指向該節(jié)點(diǎn)的下一個(gè)節(jié)點(diǎn);

Java進(jìn)階(7)——手動(dòng)實(shí)現(xiàn)LinkedList & 內(nèi)部node類(lèi)的實(shí)現(xiàn) & 增刪改查的實(shí)現(xiàn) & toString方法 & 源碼的初步理解,Java,java,開(kāi)發(fā)語(yǔ)言

    @Override
    public void remove(int index) {
        // 找到要?jiǎng)h除的節(jié)點(diǎn),前置節(jié)點(diǎn),后續(xù)節(jié)點(diǎn)
        // 1.如果刪除的是頭部節(jié)點(diǎn)
        if (index==0){
            first = NodeByIndex(index+1);
            return;
        }
        // 2.如果不是頭部節(jié)點(diǎn)
        Node<T> tNode = NodeByIndex(index); // 當(dāng)前節(jié)點(diǎn)
        Node<T> prev = tNode.prev; // 當(dāng)前節(jié)點(diǎn)的上一個(gè)節(jié)點(diǎn)
        Node<T> next = tNode.next; // 當(dāng)前節(jié)點(diǎn)的下一個(gè)節(jié)點(diǎn)
        if (next==null){
            // 刪除的是尾部節(jié)點(diǎn)
            prev.next = null;
            return;
        }
        // 刪除的是中間的某個(gè)節(jié)點(diǎn)
        // 讓該節(jié)點(diǎn)的前置節(jié)點(diǎn)的下一個(gè)節(jié)點(diǎn)指向該節(jié)點(diǎn)的下一個(gè)節(jié)點(diǎn)
        prev.next = next;
        next.prev = prev;
        size--;
    }

修改元素

被修改的節(jié)點(diǎn)的節(jié)點(diǎn)關(guān)系不變,只需要把當(dāng)前節(jié)點(diǎn)的元素變?yōu)樽钚碌脑丶纯?/p>

Java進(jìn)階(7)——手動(dòng)實(shí)現(xiàn)LinkedList & 內(nèi)部node類(lèi)的實(shí)現(xiàn) & 增刪改查的實(shí)現(xiàn) & toString方法 & 源碼的初步理解,Java,java,開(kāi)發(fā)語(yǔ)言

代碼實(shí)現(xiàn)

Java進(jìn)階(7)——手動(dòng)實(shí)現(xiàn)LinkedList & 內(nèi)部node類(lèi)的實(shí)現(xiàn) & 增刪改查的實(shí)現(xiàn) & toString方法 & 源碼的初步理解,Java,java,開(kāi)發(fā)語(yǔ)言

查詢(xún)?cè)?/h3>

調(diào)用node方法即可

    @Override
    public T get(int index) {
        // 索引不能大于等于size
        if (index<0 || index>=size){
            throw new IndexOutOfBoundsException("LinkedList的索引越界");
        }
        return NodeByIndex(index).item;
    }

toString方法

Java進(jìn)階(7)——手動(dòng)實(shí)現(xiàn)LinkedList & 內(nèi)部node類(lèi)的實(shí)現(xiàn) & 增刪改查的實(shí)現(xiàn) & toString方法 & 源碼的初步理解,Java,java,開(kāi)發(fā)語(yǔ)言

完整代碼

List接口類(lèi)

package com.tianju.book.jpa.mlist;

/**
 * 手工打造ArrayList
 */
public interface MyList<T> {
    /**
     * 增加一個(gè)元素,涉及到容量的變化
     */
    void add(T t);

    /**
     * 根據(jù)索引刪除元素
     * @param index 要?jiǎng)h除元素的索引,超過(guò)索引?索引不存在?
     */
    void remove(int index);

    /**
     * 根據(jù)索引修改一個(gè)元素
     * @param index 要修改的索引
     * @param t 修改的值
     */
    void set(int index,T t);

    /**
     * 根據(jù)索引獲取元素
     * @param index 索引
     * @return 獲取的元素
     */
    T get(int index);

    int size();

    String toString();

}

LinkedList的實(shí)現(xiàn)

package com.tianju.book.jpa.myLinkList;

import com.tianju.book.jpa.mlist.MyList;

public class MyLinkedList<T> implements MyList<T> {

    int size = 0;

    Node<T> first; // 頭部節(jié)點(diǎn)

    Node<T> last; // 尾部節(jié)點(diǎn)


    /**
     * 內(nèi)部類(lèi),節(jié)點(diǎn);屬性,當(dāng)前節(jié)點(diǎn),前置節(jié)點(diǎn),后續(xù)節(jié)點(diǎn)
     * @param <T>
     */
    private static class Node<T> {
        T item; // 當(dāng)前的節(jié)點(diǎn)
        Node<T> next; // 下一個(gè)節(jié)點(diǎn)
        Node<T> prev; // 前置節(jié)點(diǎn)

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

        @Override
        public String toString() {
            String nextStr = null;
            if (next!=null){
                nextStr = next.item.toString();
            }
            String prevStr = null;
            if (prev!=null){
                prevStr = prev.item.toString();
            }

            return "Node{" +
                    " prev=" + prevStr +
                    ",item=" + item +
                    ", next=" + nextStr +
                    '}';
        }
    }


    @Override
    public void add(T e) {
        Node<T> l = last;
        Node<T> newNode = new Node<>(l, e, null); // 新增的節(jié)點(diǎn),尾部添加

        last = newNode;
        if (l==null){
            // 是第一個(gè)節(jié)點(diǎn)
            first = newNode;
            System.out.println("FirstNode --->"+first);
        }else {
            l.next = newNode;
            System.out.println("Add {"+e+"} ---->"+l);
        }
        size++;
    }

    public Node<T> NodeByIndex(int index){
        Node<T> x = first; // 從頭部開(kāi)始找
        for (int i = 0; i<index;i++){
            x = x.next;
        }
        return x;
    }

    @Override
    public void remove(int index) {
        // 找到要?jiǎng)h除的節(jié)點(diǎn),前置節(jié)點(diǎn),后續(xù)節(jié)點(diǎn)
        // 1.如果刪除的是頭部節(jié)點(diǎn)
        if (index==0){
            first = NodeByIndex(index+1);
            return;
        }
        // 2.如果不是頭部節(jié)點(diǎn)
        Node<T> tNode = NodeByIndex(index); // 當(dāng)前節(jié)點(diǎn)
        Node<T> prev = tNode.prev; // 當(dāng)前節(jié)點(diǎn)的上一個(gè)節(jié)點(diǎn)
        Node<T> next = tNode.next; // 當(dāng)前節(jié)點(diǎn)的下一個(gè)節(jié)點(diǎn)
        if (next==null){
            // 刪除的是尾部節(jié)點(diǎn)
            prev.next = null;
            return;
        }
        // 刪除的是中間的某個(gè)節(jié)點(diǎn)
        // 讓該節(jié)點(diǎn)的前置節(jié)點(diǎn)的下一個(gè)節(jié)點(diǎn)指向該節(jié)點(diǎn)的下一個(gè)節(jié)點(diǎn)
        prev.next = next;
        next.prev = prev;
        size--;
    }

    @Override
    public void set(int index, T element) {
        // 索引不能大于等于size
        if (index<0 || index>=size){
            throw new IndexOutOfBoundsException("LinkedList的索引越界");
        }
        Node<T> tNode = NodeByIndex(index); // 當(dāng)前節(jié)點(diǎn)
        T oldVal = tNode.item; // 獲取舊的元素
        tNode.item = element; // 把當(dāng)前節(jié)點(diǎn)的元素設(shè)置成新的
//        System.out.println(oldVal);
    }

    @Override
    public T get(int index) {
        // 索引不能大于等于size
        if (index<0 || index>=size){
            throw new IndexOutOfBoundsException("LinkedList的索引越界");
        }
        return NodeByIndex(index).item;
    }

    @Override
    public int size() {
        return size;
    }

    /**
     * 為了實(shí)現(xiàn)toString方法
     */

    String str = "null-->";

    // 通過(guò)第一個(gè)節(jié)點(diǎn)遞歸調(diào)用,獲得LinkedList的鏈
    private String recursion(Node<T> first){

        if (!str.contains(first.item.toString())){
            str = str + first.item;
        }
        if (first.next==null){
            return str + "-->null";
        }
        str = str + "-->" +  first.next.item.toString();
        first = first.next;
        return recursion(first);
    }


    // 在每次調(diào)用后把str歸位;
    private void backStr(){
        str = "null-->";
    }

    @Override
    public String toString() {
        String recursion = recursion(first);
        backStr();
        return "MyLinkedList{ " + recursion +" }";
    }
}

測(cè)試類(lèi)

package com.tianju.book.jpa.myLinkList;

import org.hibernate.event.spi.SaveOrUpdateEvent;

import java.util.List;

public class MyLinkedListTest1 {
    public static void main(String[] args) {
        MyLinkedList<String> list = new MyLinkedList<>();
        list.add("PET1");
        list.add("PET2");
        list.add("PET3");
        System.out.println("**********");
        System.out.println(list);

        list.add("PET4");
        System.out.println(list);
        System.out.println(list.size());

//        System.out.println(list.get(4));
//        list.remove(0);
//        System.out.println("刪除頭部節(jié)點(diǎn)");
//        System.out.println(list);
//
//        System.out.println("刪除尾部節(jié)點(diǎn)");
//        list.remove(3-1);
//        System.out.println(list);

        System.out.println("刪除中間的節(jié)點(diǎn)");
        list.remove(2);
        System.out.println(list);

        System.out.println("進(jìn)行set");
        list.set(0, "SHI1");
        System.out.println(list);

    }
}

Java進(jìn)階(7)——手動(dòng)實(shí)現(xiàn)LinkedList & 內(nèi)部node類(lèi)的實(shí)現(xiàn) & 增刪改查的實(shí)現(xiàn) & toString方法 & 源碼的初步理解,Java,java,開(kāi)發(fā)語(yǔ)言


總結(jié)

1.linkedList的節(jié)點(diǎn),當(dāng)前,上一個(gè),下一個(gè)的思想;
2.根據(jù)index找node的方法,根據(jù)index確定從頭部還是尾部;
3.linkedlist的增刪改查的實(shí)現(xiàn),本質(zhì)是改變節(jié)點(diǎn)的信息;
4.遞歸方法實(shí)現(xiàn)自定義鏈表的toString方法;

到了這里,關(guān)于Java進(jìn)階(7)——手動(dòng)實(shí)現(xiàn)LinkedList & 內(nèi)部node類(lèi)的實(shí)現(xiàn) & 增刪改查的實(shí)現(xiàn) & toString方法 & 源碼的初步理解的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶(hù)投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包