我正在尝试创建图表的邻接列表表示。并且每个顶点在下面定义了四个不同的属性,但我只需要使用node
属性进行识别。
class Vertex{
private long node;
private String color;
private long d;
private long pi;
public Vertex(long node){
this.node = node;
}
// to String
public String toString(){
return node+"";
}
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;
}
}
我使用下面的代码读取文本文件中的数据,并在下面创建一个HashMap<Vertex, ArrayList<Vertex>>
对象。下面我的代码的问题是我总是在创建一个新对象,即使已经看过相同的node
值,即。我可以创建两个Vertex对象,并且都有node = 5
这实际上是非常低效的。此外,当我使用node = 5
更改顶点之一并说我将其color
属性更改为WHITE
时。这不会反映在同样具有node = 5
的其他Vertex对象中。
所以,我认为在这种情况下,每当我在文本文件中读取值5
两次或更多时,我真正需要的是能够复制对同一对象的引用。但我不知道最好的方法是什么?
class other_class{
public HashMap<Vertex, ArrayList<Vertex>> read_file(String file_loc) throws IOException {
HashMap<Vertex, ArrayList<Vertex>> graph = new HashMap<Vertex, ArrayList<Vertex>>();
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( Long.parseLong(line[0]) );
Vertex v_r = new Vertex( Long.parseLong(line[1]) );
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);
}
}
}
}
示例数据文件
1 5
1 2
5 1 <-- The 5 here creates a new Vertex object, which is not ideal, I want to be a copy of the reference to the Vertex object on line 1 with node equal to 5 .
答案 0 :(得分:1)
一种可能的选择是使用工厂方法而不是构造函数来创建新的Vertex对象,并尽可能重用现有的实例。
class Vertex{
...
private static Map<Long, Vertex> instances = new HashMap<Long, Vertex>();
public static synchronized Vertex getInstance(long node) {
if (instances.containsKey(node)) {
return instances.get(node);
} else {
Vertex vertex = new Vertex(node);
instances.put(node, vertex);
return vertex;
}
}
private Vertex(long node){
this.node = node;
}
...
}
答案 1 :(得分:1)
与David的回答类似
private static Vertex getVertex(Map<Long,Vertex> vs,long id) {
if(! vs.containsKey(id)) vs.put(id,new Vertex(id));
return vs.get(id);
}
public static void loadGraph() throws Exception {
HashMap<Vertex, ArrayList<Vertex>> graph = new HashMap<Vertex, ArrayList<Vertex>>();
FileInputStream fil = new FileInputStream("C:/temp/x.txt");
BufferedReader br = new BufferedReader( new InputStreamReader(fil));
String element = null;
Map<Long,Vertex> verts = new HashMap<Long,Vertex>();
while( (element = br.readLine()) != null){
String[] line = element.split("\\s+");
Vertex v_l = getVertex(verts, Long.parseLong(line[0]) );
Vertex v_r = getVertex(verts, Long.parseLong(line[1]) );
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);
}
}
}
答案 2 :(得分:0)
您可以设置HashMap<Long, Vertex>
,其中node
为关键字,vertex
对象为值。
Vertex v_l = graph.get(new Long(line[0]));
Vertex v_r = graph.get(new Long(line[1]));
您现在拥有v_l
和v_r
中之前创建的顶点的参考,或者,如果node
= line[0]
或{{1}的任何顶点的参考}还不存在,你会得到一个line[1]
,所以你知道你必须首次实例化它们。
这看起来像是作业,所以我不会提供整个方法。