所以我在研究链表时遇到了这段代码。这里的代码使用泛型,我在解决这里的一些问题时遇到了问题。
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;
}
}
那么类节点<E>
是什么意思?
我觉得E元素;意味着元素属于E.我是对的吗?
接下来是节点<E>
;这是什么意思?
答案 0 :(得分:0)
类名<E>
声明E
为泛型类型参数 - 这意味着Node
的任何实例都属于某种类型,这种类型将由实例化它的代码。 new Node<String>()
将创建一个String类型的节点,new Node<Integer>()
创建一个Integer类型的节点,依此类推。
在类中使用E
然后反映特定实例所选择的任何类型,因此如果a具有String类型的节点,我知道element
将是一个String,并且{{ 1}}将是对包含String的另一个节点的引用。
泛型的美妙之处在于使用此类型参数意味着我不需要为我想要使用的每种类型编写此类的副本,同时还要确保所有引用都是我期望的类型 - 当我期待一个字符串时,我不会让next
返回一个整数。
documentation非常好 - 泛型是一个非常大而微妙的主题,如果你想了解泛型,那么教程会对你有很大的帮助。
答案 1 :(得分:0)
您可以轻松地找到official docs以及许多其他资源来解决Java中这样一个大问题,我将尝试通过重新创建泛型的过程来解释它。&#34;。< / p>
假设您要实现问题中给出的类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;
}
}
有一天,您希望将您的实施设置为一个公共库,以便任何人都可以使用它,但是会出现一个严重的问题,即人们不会满意他们只能将MyData
类型的数据存储在您的Node
,他们希望存储他们想要的任何类型,因此您进行了一些更改 - 将element
的类型声明为Object
,以便它可以处理任何类型:
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;
}
}
现在一切都很好,但过了一段时间后你会收到一些挑剔用户的反馈意见:
Node.getElement()
的所有地方,我得到Object
类型的东西,我需要进行类型转换,这很不方便,如果我得到的话会更好getElement
是我想要的类型A
类型,但我无法阻止我将B
类型添加到Node
中,我无法找到这个bug直到在运行时发生异常,编译器可以帮助我找到bug 所以,如果您可以决定允许type
数据被允许放入Node
给用户,而不是在实施中硬编码,那么您觉得它会很棒您将在语句private ___ element;
的下划线中放置的内容是不确定的,您需要它是一个变量并由用户在使用时指定,因此该类的变量,这很好,但你需要一个地方在你可以使用它之前声明变量,最后你决定把变量的声明放在类名之后,在{ {1}}(一种新语法),然后代码将是:
<>
差不多完成但等待:您自己使用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
,您需要遵循刚刚制定的规则:将元素的类型信息传递给{ {1}}当你使用它时,所以最后你得到了以下代码:
next
Em ....对不起,我没想到会这么久......但希望它对你有点帮助。
答案 2 :(得分: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());
}
}