重复使用其他类型的链接列表(通用类型)

时间:2016-03-02 14:22:34

标签: java generics linked-list

所以我有这个链表类:

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
    }
}

2 个答案:

答案 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是否包含NodesEdges。所以我建议您保留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,假设NodeEdge都实现{{} 1}}。

我已经提到了它,但又想再强调一下:这比仅在Named内使用超NodeEdge的方法更优越。在这种情况下,您可以将LinkedListNode个实例放在同一个Edge中,编译器将无法向您发出警告。通用方法使您能够创建仅限LinkedListLinkedList或不受限制(Node)的Edge个实例。在所有情况下,编译器都会为您提供保持列表顺畅所需的支持。