2017-04-01 28 views
1

所以我在學習鏈表時遇到了這個代碼。這裏的代碼使用泛型,而我在理解這裏的一些東西時遇到了問題。瞭解java泛型中的一些概念

public static class Node<E> 
{ 
    E element; 
    Node <E> next; 
    public Node(E e,Node <E> n) 
    { 
     element=e; 
     next=n;System.out.println(next); 
    } 
    public E getelement() {return element;} 
    public Node<E> getnext(){ return next;} 
    public void setnext(Node <E> n) 
    { 
     next=n; 
    } 
} 

那麼class Node <E>是什麼意思? 我覺得E元素;意味着元素是E型的。我說得對嗎? 節點<E>下一個;這是什麼意思?

+2

https://docs.oracle.com/javase/tutorial/java/generics/ –

+2

是的,你說得對:'E element'聲明一個名爲'element'的字段,類型'E'。 'Node next'聲明一個字段名'next',類型爲'Node '。根據定義,鏈接列表包含鏈接到下一個鏈接的節點,以形成...鏈接列表。 –

+0

節點接下來將意味着下一個類的對象;節點''下一個意味着下一個是類節點的對象''? – Shuvro

回答

0

<E>類名聲明E作爲泛型類型參數 - 這意味着Node任何情況下會出現一些類型,這種類型將被實例化它的代碼來決定。 new Node<String>()將創建一個類型爲String的節點,new Node<Integer>()將創建一個類型爲Integer的節點,依此類推。

E在那麼類反射特定實例已經選擇的任何類型中使用,因此,如果有String類型的節點,我知道element將是一個字符串,和next將是包含於另一節點的參考一個字符串。

泛型的美妙之處在於使用這個類型參數意味着我不需要爲每個我想要使用的類型編寫這個類的副本,同時還要確保所有引用都是I類型的期望 - 當我期待String時,我不會得到next返回一個Integer。

link JB Nizet provides是一個非常好的 - 泛型是一個相當大的和微妙的話題,如果你想了解泛型,該教程將幫助你很多。

0

你可以很容易地找到official docs和其他許多資源,用於Java這樣的大話題,我會試着用「重新創建泛型的過程」來解釋它。

說你要實現的問題給類Node,它是LinkedList的一個基本組成單位,所以你將它定義爲:

class Node { 
    private Node next; 

    public Node getNext() { 
     return next; 
    } 

    public void setNext(Node n) { 
     next = n; 
    } 
} 

,但你需要一些數據存儲在每個Node ,不是嗎,否則這個班是無用的。顯然多了一個字段是必要的,要存儲類型爲MyData,那麼它會是:你想

class Node { 
    private MyData element; 
    private Node next; 

    public Node getNext() { 
     return next; 
    } 

    public MyData getElement() { 
     return element; 
    } 

    public void setElement(MyData element) { 
     this.element = element; 
    } 

    public void setNext(Node n) { 
     next = n; 
    } 
} 

一天,讓您實現一個公共庫,因此它可以被任何人使用,但一嚴重的問題出現了這人不會滿意,他們可以在你的NodeMyData型只能存儲數據,他們要存儲任何他們想要的類型,所以你做了一點改變 - 申報elementObject的類型,以便它可以處理任何類型:

class Node { 
    private Object element; 
    private Node next; 

    public Node getNext() { 
     return next; 
    } 

    public Object getElement() { 
     return element; 
    } 

    public void setElement(Object element) { 
     this.element = element; 
    } 

    public void setNext(Node n) { 
     next = n; 
    } 
} 

Everythi NG現在的好,但過一段時間後,你從一些挑剔的用戶會收到一些反饋:

  • 用戶A:我到處打電話Node.getElement()在我的代碼,我得到一個Object類的東西,我需要做一個類型轉換,這不方便,如果我從getElement得到的是我想要的類型
  • 用戶B:這個錯誤,直到運行時發生異常爲止,編譯器可以幫助我找到該錯誤更好:

所以你覺得如果你允許數據的type被允許放在用戶的Node中,而不是在實現中進行硬編碼,這意味着你將放在下劃線的位置陳述private ___ element;是不確定的,你需要它是一個變量,並由用戶在他們使用它的時刻指定,所以變量到類,這很好,但你需要一個地方聲明變量,然後才能使用它,最後你決定在<>(一個新的語法)裏面放上類名後面的變量聲明,那麼代碼將是:

class Node<E> { 
    private E element; 
    private Node next; 

    public E getElement() { 
     return element; 
    } 

    public void setElement(E element) { 
     this.element = element; 
    } 

    public Node getNext() { 
     return next; 
    } 

    public void setNext(Node n) { 
     next = n; 
    } 
} 

幾乎完成,但等待:你使用Node自己 - 現場next,你需要按照你剛纔的規則:元素通型信息,以Node在當您使用它時間,所以最後你得到的代碼如下:

class Node<E> { 
    private E element; 
    private Node<E> next; 

    public E getElement() { 
     return element; 
    } 

    public void setElement(E element) { 
     this.element = element; 
    } 

    public Node<E> getNext() { 
     return next; 
    } 

    public void setNext(Node<E> n) { 
     next = n; 
    } 
} 

恩....對不起,我沒有想到這會這麼長......但希望它可以對你有點幫助。

0

我總能從中學到例如最好的,所以就把Node一個簡單的使用:

import java.awt.Point; 

public class TestNode{ 

    public static void main(String[] args) { 

     //assume you have 3 points 
     Point point1 = new Point(40,40); 
     Point point2 = new Point(80,120); 
     Point point3 = new Point(70,200); 

     //each point is connected to one other point. to represent such connection you 
     //can create a Node<Point> or in other words Node of Point. 
     //define the last node in the chain, which has no next node: 
     Node<Point> node3 = new Node<>(point3, null); 
     //Note: because Node<E> is generic you could define Node<Cats>, Node<Dogs>, Node<AnyType> 

     //define the point2-point3 connection 
     Node<Point> node2 = new Node<>(point2, node3); 
     //define point1-point2 connection 
     Node<Point> node1 = new Node<>(point1, node2); 

     //now put it to test. node1.getnext() return node2, node1.getnext().getelement() returns point2 
     System.out.println("Point 2 x-y " +node1.getnext().getelement().getX() 
                   +"-"+node1.getnext().getelement().getY()); 

     //now put it to test. node1.getnext().getnext() return node3 
     System.out.println("Point 3 x-y " +node1.getnext().getnext().getelement().getX() 
                +"-"+node1.getnext().getnext().getelement().getY()); 
    } 
}