2014-12-16 2 views
0

В принципе, я пытаюсь читать в текстовом файле, используя следующий код, чтобы построить граф, используя представление списков смежности. Однако я столкнулся с двумя проблемами.Java: Как проверить ключи hashmap содержат объект?

Первой и главной проблемой является то, что: я не понимаю, когда я проверяю graph.contains(v_l), он всегда возвращает false. Я уже давно цепляюсь за эту проблему. На самом деле нужна помощь здесь.

Вторая проблема: я не понимаю, почему это в if заявление, я не могу сделать следующее:

if(graph.containsKey(v_l) == false){ 
       // this always fail    
       graph.put(v_l, edges_of_this_vertex.add(v_r)); 
       // the following works though 
       ArrayList<Vertex> edges_of_this_vertex = new ArrayList<Vertex>(); 
       edges_of_this_vertex.add(v_r); 
       graph.put(v_l, edges_of_this_vertex); 
} 

Я понятия не имею, почему это происходит?

class Vertex{ 
      int node; 
      .... 
      public Vertex(int node){ 
       this.node = node; 
      } 

      public String toString(){ 
       return Integer.toString(node); 
      } 
    } 
class dgraph{ 
// constructor ... 

// instance method 
public HashMap<Vertex, ArrayList<Vertex>> read_file_and_populate(String file_loc, boolean reverse) throws IOException{ 

     HashMap<Vertex, ArrayList<Vertex>> graph = new HashMap<Vertex, ArrayList<Vertex>>(); 
     int l = 0; 
     int r = 0; 
     if(reverse == false){ 
      r = 1; 
     } else{ 
      l = 1; 
     } 

     FileInputStream fil = new FileInputStream(file_loc); 
     BufferedReader br = new BufferedReader(new InputStreamReader(fil)); 
     String element = null; 

     while((element = br.readLine()) != null){ 
      String[] line = element.split("\\s"); 
      Vertex v_l = new Vertex(Integer.parseInt(line[l])); 
      Vertex v_r = new Vertex(Integer.parseInt(line[r])); 
      System.out.println("l = " + l + " r = " + r); 
      if(graph.containsKey(v_l) == false){ 
       ArrayList<Vertex> edges_of_this_vertex = new ArrayList<Vertex>(); 
       edges_of_this_vertex.add(v_r); 
       graph.put(v_l, edges_of_this_vertex); 
       //graph.put(v_l, edges_of_this_vertex.add(v_r)); 
      } else{ 
       graph.get(v_l).add(v_r); 

      } 
     } 
     return graph; 
    } 
} 

Ниже приведены примеры, данные:

1 1 
1 2 
1 5 
1 6 
1 7 
1 3 
1 8 
1 4 
2 47646 
2 47647 
2 13019 
2 47648 
2 47649 
2 47650 
2 7700 
2 47651 
2 47652 
3 511596 
5 1 
5 9 

ответ

1

Ваше значение класса (Vertex) необходимо реализовать хэш-код & Equals(), в противном случае все операции будут делать проверку, чтобы увидеть, если его же экземпляр (который никогда не будет в этом случае). предполагая, что int является единственным состоянием в Vertex, функции hashCode & равны, должны быть основаны на тех, например.

public int hashCode() { 
    return node *31; 
} 

public boolean equals(Object o) { 
    if (o == this) return true; 
    if (o == null || getClass() != o.getClass()) return false; 
    Vertex r = (Vertex)o; 
    return node == r.node; 
} 
+0

'int node' - не единственная переменная экземпляра в классе Vertex, но это единственная переменная, которую я бы использовал для сравнения разных объектов Vertex. Будет ли ваше решение по-прежнему работать в этом случае? И что именно делает метод hashCode()? Я имею в виду, почему нам нужно делать 'node * 31'? Разве мы не можем просто вернуть «узел»? – mynameisJEFF

+0

да, это все равно сработает. – superfell

+0

В этом вопросе подробно обсуждается hashCode http://stackoverflow.com/questions/113511/hash-code-implementation – superfell

0

В

// this always fail    
      graph.put(v_l, edges_of_this_vertex.add(v_r)); 

вы пытаетесь добавить результат edges_of_this_vertex.add (V_r) на графике. Функция add() для arraylist возвращает логическое значение (всегда true). Итак, когда вы выполняете функцию graph.get (v_l), вы всегда получите логическое значение true.