简体   繁体   English

Java:不可能使用迭代器来迭代对象的HashMap并更改对象的属性吗?

[英]Java: Is it not possible to use an iterator to iterate a HashMap of objects and change attributes of objects?

I know this may be a very basic question to the experts in here. 我知道这对这里的专家来说可能是一个非常基本的问题。 But I cannot get my head around this. 但是我无法解决这个问题。 Basically, I have the following depth-first-search instance method. 基本上,我有以下深度优先搜索实例方法。 I have an object class Dgraph , which is HashMap<Vertex, ArrayList<Vertex>> . 我有一个对象类Dgraph ,它是HashMap<Vertex, ArrayList<Vertex>> Vertex is just an object class I created and it contains a color attribute and a node attribute. Vertex只是我创建的对象类,它包含一个color属性和一个node属性。

Problem: Basically, I want to change the color of the Vertex object within the iterator statement. 问题:基本上,我想更改iterator语句中Vertex对象的颜色。 But it doesn't work as expected. 但是它没有按预期工作。 I was able to change the color attribute of each vertex object within the iterator but when I leave the iterator , the color attribute of each vertex are still null . 我能够更改迭代器中每个顶点对象的color属性,但是当我离开迭代器时,每个顶点的color属性仍然为null

Note that Vertex objects with same node values are the same object , ie consider 5 --> 1 and 1 -- 9 , we only have one Vertex object with node equal to 1 here. 注意,具有相同节点值的Vertex对象是同一对象 ,即考虑5 --> 11 -- 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();
    }
}

This is the debugging output I got: 这是我得到的调试输出:

Before iterator
Graph = Dgraph@7852e922

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

I removed my toString method, so you guys can take a look at the references and check some of them referring to the same object. 我删除了toString方法,因此你们可以看看引用,并检查其中的一部分引用同一对象。

Before iterator
Graph = Dgraph@7852e922

Vertex@9b : [Vertex@1f, Vertex@117]
    null    null
Vertex@5d : [Vertex@f1ff14]
    null
Vertex@3e : [Vertex@1689a2, Vertex@1689c1, Vertex@62885, Vertex@1689e0, Vertex@1689ff, Vertex@168a1e, Vertex@3a46c, Vertex@168a3d, Vertex@168a5c]
    null    null    null    null    null    null    null    null    null
Vertex@1f : [Vertex@1f, Vertex@3e, Vertex@9b, Vertex@ba, Vertex@d9, Vertex@5d, Vertex@f8, Vertex@7c]
    null    null    null    null    null    null    null    null
in iterator --> Vertex u = Vertex@9b color = WHITE
in iterator --> Vertex u = Vertex@5d color = WHITE
in iterator --> Vertex u = Vertex@3e color = WHITE
in iterator --> Vertex u = Vertex@1f color = WHITE
*************************
After iterator
Graph = {Vertex@9b=[Vertex@1f, Vertex@117], Vertex@5d=[Vertex@f1ff14], Vertex@3e=[Vertex@1689a2, Vertex@1689c1, Vertex@62885, Vertex@1689e0, Vertex@1689ff, Vertex@168a1e, Vertex@3a46c, Vertex@168a3d, Vertex@168a5c], Vertex@1f=[Vertex@1f, Vertex@3e, Vertex@9b, Vertex@ba, Vertex@d9, Vertex@5d, Vertex@f8, Vertex@7c]}

Vertex@9b : [Vertex@1f, Vertex@117]
    null    null
Vertex@5d : [Vertex@f1ff14]
    null
Vertex@3e : [Vertex@1689a2, Vertex@1689c1, Vertex@62885, Vertex@1689e0, Vertex@1689ff, Vertex@168a1e, Vertex@3a46c, Vertex@168a3d, Vertex@168a5c]
    null    null    null    null    null    null    null    null    null
Vertex@1f : [Vertex@1f, Vertex@3e, Vertex@9b, Vertex@ba, Vertex@d9, Vertex@5d, Vertex@f8, Vertex@7c]
    WHITE   null    null    null    null    null    null    null

UPDATE: The instance method returnHashMap sits in the class Dgraph as follow: 更新:实例方法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;
    }
    .....
}

The Vertex class is shown below: Vertex类如下所示:

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

This is the display method that I am using: 这是我正在使用的显示方法:

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 : Below is the code that I used to create the HashMap. 更新 :以下是我用来创建HashMap的代码。 I thought I was creating a HashMap such that if two Vertex objects with the same node value appear in the key and in the value , they would share the same memory address and point to the same Vertex Object (ie there should only be one Vertex Object). 我以为我正在创建一个HashMap,这样如果两个具有相同节点值的顶点对象出现在键和值中,它们将共享相同的内存地址并指向相同的顶点对象(即,应该只有一个顶点对象) )。

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

You modify the color of the keys , but the display method only prints the colors of the values . 您可以修改的颜色,但是显示方法只能打印的颜色。 You have one Vertex which is a key and a value ("Vertex@1f"), which is why you have the lone "WHITE" output in the bottom row of your output. 您有一个作为键和值的顶点(“ Vertex @ 1f”),这就是为什么在输出的底行有单独的“ WHITE”输出的原因。

UPDATE: 更新:

Look at this line (note its placement in the code flow): 查看这一行(请注意其在代码流中的位置):

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM