通用迭代器的声明

时间:2018-07-01 09:10:24

标签: java generics iterator raw-types

我正在编程一个称为graph的类,并通过Hashmap表示有向图。我想创建一种以以下方式打印出整个图形的方法:

key1: value13, valeue17, ..
key2: value21, ...

其中value13是node1(key1)指向的node3的值。 因此,对于1-> 2-> 3之类的东西,而2也指向4,我需要:

1: 2
2: 3,4

我的代码如下:

public class Graph<T>{
  Map<Node<T>, List<Node<T>>> graph;

  //constructors and methods

  void printGraph(){
    System.out.println(graph.keySet().iterator().next().value); // is printing 7
    Iterator itKey = graph.keySet().iterator();
    System.out.println(itKey.next()); // printing Graph$Node@15db9742
    System.out.println(itKey.next().value); //error
    while(itKey.hasNext()){
    //code
  }

  public static void main(String[] args){
    Graph<Integer> graph = new Graph<>();
    Node<Integer> n1 = new Node<>(7);
    Node<Integer> n2 = new Node<>(2);
    graph.connect(n1, n2);
    graph.printGraph();
  }
}

我的问题出现在方法printGraph()中,其中定义了一个Iterator。我想要做的是创建一个迭代器 在该组键上,然后为每个键创建一个迭代器,该迭代器将打印所有值。如您所见,如果我尝试打印System.out.println(graph.keySet().iterator().next().value); 我得到一个7,这很有意义,因为它是我的keySet()中第一个键的值。如果我用另一种方式做,初始化迭代器Iterator itKey = graph.keySet().iterator();,则这是指向Node的迭代器:

System.out.println(itKey.next()); // printing Graph$Node@15db9742

但是,如果我尝试打印其值:

System.out.println(itKey.next().value); //error

我收到以下错误:

error: cannot find symbol
    System.out.println(itKey.next().value);
                                   ^
  symbol:   variable value
  location: class Object
1 error

这不是同一回事吗?为什么会出现错误?

3 个答案:

答案 0 :(得分:2)

这是编译错误,因为您的Iterator itKey具有原始类型;因此,对itKey.next()的调用将返回Object。您想为迭代器指定正确的类型,以便iterator.next()的返回类型为Node

在您的代码中,只需更改itKey变量的类型

  void printGraph() {
    System.out.println(graph.keySet().iterator().next().value);
    // use the non-raw type here
    Iterator<Node<T>> itKey = graph.keySet().iterator();
    System.out.println(itKey.next());
    System.out.println(itKey.next().value); 
    while (itKey.hasNext()) {
      // code
    }
  }

System.out.println(graph.keySet().iterator().next().value);行会编译,因为不会丢失任何类型信息。查看涉及的类型:

  • graph变量的类型为Map<Node<T>, List<Node<T>>>
  • graph.keySet()的类型为Set<Node<T>>
  • graph.keySet().iterator()的类型为Iterator<Node<T>>
  • graph.keySet().iterator().next()的类型为Node<T>

,由于最后一个next()的类型是Node,因此我们可以获取其value

答案 1 :(得分:0)

您应该提供通用迭代器,而不是非通用。如果是非通用类型,则它返回 Object 类型作为元素,然后需要将其类型转换为不好的Node,因此最好在获取Iterator实例时定义类型。

 Iterator<Node<T>> itKey = graph.keySet().iterator();

 while(itKey.hasNext()){
         System.out.println(itKey.next().value);    
}

答案 2 :(得分:0)

您的

itKey.next().value 

给出错误,因为迭代器不知道value是什么。 可能itKey.next()强制转换为Node会起作用,但那不是打印图形的最理想方法。

您可以使用以下方法进行相同操作。它使用条目集来迭代graph映射。

printGraph功能:

void printGraph() {
    for (Map.Entry<Node<T>, List<Node<T>>> entry : graph.entrySet()) {
        Node<T> fromNode = entry.getKey();
        System.out.print(fromNode.value + " ->");
        for (Node<T> toNode : entry.getValue())
            System.out.print(" " + toNode.value);
        System.out.println();
    }
}

main功能:

Node<Integer> n1 = new Node<>(1);
Node<Integer> n2 = new Node<>(2);
Node<Integer> n3 = new Node<>(3);
Node<Integer> n4 = new Node<>(4);
Node<Integer> n5 = new Node<>(5);

Graph<Integer> graph = new Graph<>();
graph.connect(n1, n2);
graph.connect(n1, n3);
graph.connect(n4, n5);

graph.printGraph();

打印:

4 -> 5
1 -> 2 3