Объявление универсальных итераторов - PullRequest
0 голосов
/ 01 июля 2018

Я программирую класс с именем graph и представляю ориентированный граф с помощью Hashmap. Я хочу создать метод, который распечатывает весь график следующим образом:

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

где value13 - это значение узла3, на который указывает узел1 (ключ1). Итак, для чего-то вроде 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 голосов
/ 01 июля 2018

Ваш

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
0 голосов
/ 01 июля 2018

Это ошибка компиляции, потому что ваш Iterator itKey имеет тип raw; поэтому вызов 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.

0 голосов
/ 01 июля 2018

Вы должны предоставить универсальный итератор, а не универсальный. Если не универсальный тип возвращаемого значения Object в качестве элемента, а затем необходимо типизировать его к узлу, что не очень хорошо, так что лучше определить тип при получении экземпляра Iterator.

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

 while(itKey.hasNext()){
         System.out.println(itKey.next().value);    
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...