2014-12-17 1 views
1

Я знаю, что это может быть очень простой вопрос для экспертов здесь. Но я не могу обдумать это. В принципе, у меня есть следующий метод экземпляра глубины поиска. У меня есть класс объектов Dgraph, который составляет HashMap<Vertex, ArrayList<Vertex>>. Vertex - это только класс объектов, который я создал, и он содержит атрибут color и атрибут node.Java: нельзя ли использовать итератор для итерации HashMap объектов и изменения атрибутов объектов?

Проблема: В принципе, я хочу изменить цвет объекта Вершины в инструкции итератора. Но это работает не так, как ожидалось. Я смог изменить атрибут color каждого объекта вершин в итераторе, но когда я покинул итератор, атрибут цвета каждой вершины все еще null.

Обратите внимание, что объекты Vertex с теми же значениями узлов являются тем же объектом, то есть рассмотреть 5 --> 1 и 1 -- 9, у нас есть только один объект Vertex с узлом, равным 1 здесь.

public void depth_first_search(Dgraph graph){ 
     // for debugging 
     System.out.println("Before iterator"); 
     System.out.println("Graph = " + graph); 
     System.out.println(""); 
     graph.display(); 
    HashMap<Vertex, ArrayList<Vertex>> dag = graph.returnHashMap(graph); 
    for(Map.Entry<Vertex, ArrayList<Vertex>> g_map : dag.entrySet()){ 
     Vertex u = g_map.getKey(); 
     u.set_color("WHITE"); 
     System.out.println("In iterator --> Vertex u = " + u + " color = " + u.get_color()); 
    } 
    // for debugging 
    System.out.println("*************************"); 
    System.out.println("After iterator"); 
    System.out.println("Graph = " + dag); 
    graph.display(); 
    } 
} 

Это отладочный я получил:

Before iterator 
Graph = [email protected] 

5 : [1, 9] 
    null null 
3 : [511596] 
    null 
2 : [47646, 47647, 13019, 47648, 47649, 47650, 7700, 47651, 47652] 
    null null null null null null null null null 
1 : [1, 2, 5, 6, 7, 3, 8, 4] 
    null null null null null null null null 
in iterator --> Vertex u = 5 color = WHITE 
in iterator --> Vertex u = 3 color = WHITE 
in iterator --> Vertex u = 2 color = WHITE 
in iterator --> Vertex u = 1 color = WHITE 
************************* 
After iterator 
Graph = {5=[1, 9], 3=[511596], 2=[47646, 47647, 13019, 47648, 47649, 47650, 7700, 47651, 47652], 1=[1, 2, 5, 6, 7, 3, 8, 4]} 

5 : [1, 9] 
    null null 
3 : [511596] 
    null 
2 : [47646, 47647, 13019, 47648, 47649, 47650, 7700, 47651, 47652] 
    null null null null null  null null null null 
1 : [1, 2, 5, 6, 7, 3, 8, 4] 
    WHITE null  null null null null null  null 

Я удалил свой toString метод, так что вы, ребята, можете посмотреть на ссылки и проверить некоторые из них со ссылкой на тот же объект.

Before iterator 
Graph = [email protected] 

[email protected] : [[email protected], [email protected]] 
    null null 
[email protected] : [[email protected]] 
    null 
[email protected] : [[email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected]] 
    null null null null null null null null null 
[email protected] : [[email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected]] 
    null null null null null null null null 
in iterator --> Vertex u = [email protected] color = WHITE 
in iterator --> Vertex u = [email protected] color = WHITE 
in iterator --> Vertex u = [email protected] color = WHITE 
in iterator --> Vertex u = [email protected] color = WHITE 
************************* 
After iterator 
Graph = {[email protected]=[[email protected], [email protected]], [email protected]=[[email protected]], [email protected]=[[email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected]], [email protected]=[[email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected]]} 

[email protected] : [[email protected], [email protected]] 
    null null 
[email protected] : [[email protected]] 
    null 
[email protected] : [[email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected]] 
    null null null null null null null null null 
[email protected] : [[email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected]] 
    WHITE null null null null null null null 

ОБНОВЛЕНИЕ: Метод экземпляра returnHashMap сидит в классе Dgraph следующим образом:

class Dgraph{ 

    // instance variable 
    HashMap<Vertex, ArrayList<Vertex>> dag; 

    // constructor 
    public Dgraph(String file, boolean reverse) throws IOException{ 
     dag = read_file_and_populate(file, reverse); 
    } 

    public HashMap<Vertex, ArrayList<Vertex>> returnHashMap(Dgraph g){ 
     return g.dag; 
    } 
    ..... 
} 

Класс вершинных показан ниже:

class Vertex{ 
    private long node; 
    private String color; 
    private long d; 
    private long pi; 
    private long f; 

public Vertex(long node){ 
    this.node = node; 
} 

// return color 
public String get_color(){ 
    return color; 
} 

// change color 
public void set_color(String color){ 
    this.color = color; 
} 

// return distance 
public long get_d(){ 
    return d; 
} 

// change distance 
public void set_d(long d){ 
    this.d = d; 
} 

// return predecessor 
public long get_pi(){ 
    return pi; 
} 

// assign predecessor 
public void set_pi(long pi){ 
    this.pi = pi; 
} 

// to String (prevent print reference) 
public String toString(){ 
    return node+""; 
} 

// return node 
public long get_node(){ 
    return node; 
} 

// return finishing time 
public long get_f(){ 
    return f; 
} 

// set finishing time 
public void set_f(long f){ 
    this.f = f; 
} 

// Need hashCode() and equals() to compare objects 
public int hashCode(){ 
    return (int)(node * 31); 
} 

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

Это метод отображения, который Я использую:

public void display(){ 
    for(Map.Entry<Vertex, ArrayList<Vertex>> entry : dag.entrySet()){ 
     System.out.println(entry.getKey() + " : " + entry.getValue()); 
     for(Iterator<Vertex> iterator = dag.get(entry.getKey()).iterator(); iterator.hasNext();){ 
      Vertex vv = iterator.next(); 
      System.out.print("\t" + vv.get_color()); 
     } 
     System.out.println(""); 

    } 
} 

UPDATE: Ниже приведен код, который я использовал для создания HashMap. Я думал, что создаю HashMap таким образом, что если в ключе и в значении появляются два объекта Vertex с одним и тем же значением узла, они будут разделять один и тот же адрес памяти и указывать на один и тот же объект Вершины (т. Е. Должен быть только один объект Вершины).

public Vertex getVertex(Map<Long,Vertex> vertices_map, long node){ 
     if(! vertices_map.containsKey(node)) vertices_map.put(node, new Vertex(node)); 
     return vertices_map.get(node); 
    } 

    // read file and return graphs 
    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"); 
     /* 
     * 
     * Create a new vertex object when the node first occurs; 
     * And if the node occurs more than once, return a copy of the 
     * reference to the same object with the same node value. 
     * 
     */ 
     HashMap<Long, Vertex> vertices_map = new HashMap<Long, Vertex>(); 
     Vertex v_l = getVertex(vertices_map , Long.parseLong(line[l])); 
     Vertex v_r = getVertex(vertices_map , Long.parseLong(line[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); 
     } else{ 
      graph.get(v_l).add(v_r); 
     } 
    } 
    return graph; 
} 
+1

Что ваш метод returnHashMap делать? –

+0

@LouisWasserman Я только что обновил вопрос и объяснил, что делает метод экземпляра 'returnHashMap' в моем коде.Он по существу возвращает HashMap вершин (ключ) и arraylist вершин (значений). – mynameisJEFF

+2

показать класс вершин. – jtahlborn

ответ

2

Вы изменить цвет ключей, но метод отображения только печатает цвета на значений. У вас есть один Vertex, который является ключом и значением («Vertex @ 1f»), поэтому у вас есть единственный выход «WHITE» в нижней строке вашего вывода.

UPDATE:

Посмотрите на этой линии (отметьте его размещение в потоке кода):

HashMap<Long, Vertex> vertices_map = new HashMap<Long, Vertex>(); 
+0

, но если вы посмотрите на вывод адреса памяти, который я опубликовал, например 'в итераторе Vertex u = Vertex @ 3e color = WHITE', это фактически соответствует объекту Vertex с узлом = 2 и отображается в ключе и в значение также. Я хочу сказать, что те же объекты Вершины в моем коде могут появляться в ключах и в значениях таких, что если я вношу какие-либо изменения в конкретный объект Вершины, изменения будут отражены во всей HashMap. – mynameisJEFF

+1

Почему бы вам не попробовать изменить метод 'Vertex.toString()' для включения цвета: 'return node +" "+ color;'? – jtahlborn

+0

О! Ты прав!!! Почему это происходит ? Изменяется только цвет клавиш. Но я думал, что в соответствии с выведенным мной адресом памяти, ссылка на ключ и ссылка на значения указывают на объект SAME. Я сейчас очень озадачен. – mynameisJEFF

Смежные вопросы