所以我有这个链表类:
public class LinkedList {
private LLNode rootNode;
public Node FindItemByData(String data) {
if(rootNode == null)
return null;
else
return rootNode.findItemByData(data);
}
这个节点类:
public class LLNode {
LLNode tail; //tail node
Node data; //some data
public LLNode(LLNode tail, Node data)
{
this.tail = tail;
this.data = data;
}
public Node findItemByData(String data) {
if(this.data.name.equals(data))
return this.data;
else
return this.tail.findItemByData(data);
}
我想重新使用链表在LLNode的每个Node data
内的图表中存储边缘。我曾经使用Generic Types替换类型,但这会破坏findItemByData
函数的功能,因为它依赖于显式声明为Node的数据。
有什么方法可以将这个类重用于多种类型?或者我不应该在通用类中引用data.name
?
实施背景:
public class Graph {
//USE LINKED LIST
LinkedList Nodes;
//Node[] Nodes;
int noOfNodes;
public Graph() {
noOfNodes = 0;
//Nodes = new Node[25];
Nodes = new LinkedList();
}
public void AddNode(String name, int x, int y) {
//Nodes[noOfNodes++] = new Node(name,x,y);
Nodes.AddItem(new Node(name,x,y));
}
...
public class Node {
String name; //Node's name
int x,y; //Node's coords
LinkedList Adjacencies;
int noOfAdj = 0;
int size = 0;
public Node(String name, int x, int y) { //Constructor
this.name = name;
this.x = x;
this.y = y;
Adjacencies = new LinkedList();
}
public void addAdjacency(String dest, double distance) {
Adjacencies.AddItem(new Edge(this.name, dest, distance)); //I want to do this
}
}
编辑:尝试使用泛型:
public class LinkedList<T> {
private LLNode rootNode;
public T FindItemByData(String data) {
if(rootNode == null)
return null;
else
return rootNode.findItemByData(data);
}
}
public class LLNode<T> {
LLNode tail; //tail node
T data; //some data
public LLNode(LLNode tail, T data)
{
this.tail = tail;
this.data = data;
}
public T findItemByData(String data) {
if(this.data.name.equals(data))
return (T) this.data;
else
return (T) this.tail.findItemByData(data);
}
}
public class Graph {
LinkedList<Node> Nodes;
int noOfNodes;
public Graph() {
noOfNodes = 0;
Nodes = new LinkedList();
}
public void AddNode(String name, int x, int y) {
Nodes.AddItem(new Node(name,x,y));
}
}
public class Node {
String name; //Node's name
int x,y; //Node's coords
LinkedList<Edge> Adjacencies;
int noOfAdj = 0;
int size = 0;
public Node(String name, int x, int y) { //Constructor
this.name = name;
this.x = x;
this.y = y;
Adjacencies = new LinkedList();
}
public void addAdjacency(String dest, double distance) {
Adjacencies.AddItem(new Edge(this.name, dest, distance)); //I want to do this
}
}
答案 0 :(得分:1)
基本上你说Node和Edge应该遵守相同的合同。要做到这一点,你应该让他们实现一个包含该合同中所有方法的接口。
在这种情况下,这可能只是public class Edge extends Node
。然后将此接口用于可以采用任何Edge或Node的方法。
另一种方法是使Edge成为Node的扩展。 $qb
->select('z')
->where($qb->expr()->orX(
$qb->expr()->like('z.city', ':czRequest')
))
->groupBy('z.city')
->setParameter('czRequest', $cz . '%');
。然后,您可以在需要节点时使用它。
答案 1 :(得分:1)
我认为你对仿制药的尝试实际上非常接近。它的优点是使编译器能够判断特定LinkedList
是否包含Nodes
或Edges
。所以我建议您保留LinkedList
的通用参数化,但要使它有点不同。 T
应该是LLNode
中保存的数据类型。诀窍是你的数据有一个String name
,所以你需要一些可以扩展的东西来获得name
。
interface Named {
String getName();
}
public class LinkedList<T extends Named> {
private LLNode<T> rootNode;
// etc.
}
public class LLNode<T extends Named> {
LLNode<T> tail; //tail node
T data; //some data
public LLNode(LLNode<T> tail, T data) {
this.tail = tail;
this.data = data;
}
public T findItemByData(String data) {
if(this.data.getName().equals(data))
return this.data;
else
return this.tail.findItemByData(data);
}
// etc.
}
现在,您可以实例化LinkedList
仅包含Nodes
,另一个只包含Edges
,假设Node
和Edge
都实现{{} 1}}。
我已经提到了它,但又想再强调一下:这比仅在Named
内使用超Node
和Edge
的方法更优越。在这种情况下,您可以将LinkedList
和Node
个实例放在同一个Edge
中,编译器将无法向您发出警告。通用方法使您能够创建仅限LinkedList
,LinkedList
或不受限制(Node
)的Edge
个实例。在所有情况下,编译器都会为您提供保持列表顺畅所需的支持。