与建筑商的最后障碍
我有一个使用构建器(J Bloch 风格)的图(g)。需要反转图表才能运行某些统计数据,然后将其缓存以供报告和分析算法访问。
因此,图 g 定义了以下参考变量:
private final Builder savedBuilder; // save builder for clone build with same properties.
private final Graph gPrime; // must reverse populated graphs BEFORE cache of stats
注意:gPrime 指的是一个相同的图,只不过它是由反转的 g 填充的。 gPrime.gPrime 应该引用 g,因为 g 是 gPrime 的逆向。
和构建器构建方法:
public Graph build() {
Graph g = new Graph(this);
g.gPrime.gPrime = g;
return g;
}
以及采用构建器的构造函数:
private Graph (Builder builder){ // 'this' used for clarity
this.gType = builder.gType;
this.dropOrphans = builder.dropOrphans;
this.fileHandle = builder.fileHandle;
this.nodes = builder.nodes;
this.edges = builder.edges;
this.delimiter = builder.delimiter;
this.mapCapacity = builder.mapCapacity;
this.mapLoadFactor = builder.mapLoadFactor;
this.savedBuilder = builder; // save builder for cloning
emptyGraph(); // build empty structure for data in this graph
if (this.fileHandle == null) { // no file data
if (this.nodes == 0) { // no sizing info
; // nothing else to do - - - empty graph
} else { // we have # of nodes
if ( this.edges == 0) { // just an edge-less integer graph)
populateEdgeless(nodes) ;
} else { // randomly generated graph
populateRandom(nodes, edges);
}
}
} else { // populate from file
populateFromFile();
}
// To create empty graph to transpose our values into,
// we need to clear out builder settings that would populate a new graph.
savedBuilder.fileHandle = null;
savedBuilder.nodes = 0;
savedBuilder.edges = 0;
// otherwise, everything the same, so just pass modified builder to constructor
// save the reference to this graph ( ready for the reversal method to use )
this.gPrime = new Graph(savedBuilder);
)
再次。目标是两个图形对象,每个对象中的 gPrime 都引用另一个对象。
顺序是: 构建 g - - - 填充 g - - - 将 g 反转为与 g 具有相同特征的空图
所以,这是我不太明白的问题。
如果我将 g 分配给 gPrime.gPrime,无论是在 g 我们构建之后的构建中还是在构造函数的底部,我都会收到一条错误消息,指出 gPrime 是最终的。 Eclipse 表明这是第一个有问题的 gPrime - - - 这是真的 - - - 它是最终的并且已被分配。但 gPrime.gprime (重点是第二个 gPrime )尚未分配。 (我搜索了整个程序。)
我还尝试将作业放在反向方法的底部。同样的事情。
我还在构建器中尝试了 g.gPrime.gPrime 。同样的事情。
就好像编译器对哪个 gPrime 正在接收分配感到困惑。
我确信有些东西我没有看到或理解 - - - 但是 - - - 不知道如何实现这一点。
如果我拿出决赛,我就能完成这项工作,但我正在努力做到一成不变。
I have a graph (g) that uses a builder ( J Bloch style ). The graph needs to be reversed to run certain statistics that are then cached for reports and analysis algorithms to access.
So, graph g defines the following reference variables:
private final Builder savedBuilder; // save builder for clone build with same properties.
private final Graph gPrime; // must reverse populated graphs BEFORE cache of stats
Note: gPrime refers to an identical graph except it is populated from the revesed g.
gPrime.gPrime should refer to g, since g is the reverse of gPrime.
and the builder build method:
public Graph build() {
Graph g = new Graph(this);
g.gPrime.gPrime = g;
return g;
}
and the constructor that takes the builder:
private Graph (Builder builder){ // 'this' used for clarity
this.gType = builder.gType;
this.dropOrphans = builder.dropOrphans;
this.fileHandle = builder.fileHandle;
this.nodes = builder.nodes;
this.edges = builder.edges;
this.delimiter = builder.delimiter;
this.mapCapacity = builder.mapCapacity;
this.mapLoadFactor = builder.mapLoadFactor;
this.savedBuilder = builder; // save builder for cloning
emptyGraph(); // build empty structure for data in this graph
if (this.fileHandle == null) { // no file data
if (this.nodes == 0) { // no sizing info
; // nothing else to do - - - empty graph
} else { // we have # of nodes
if ( this.edges == 0) { // just an edge-less integer graph)
populateEdgeless(nodes) ;
} else { // randomly generated graph
populateRandom(nodes, edges);
}
}
} else { // populate from file
populateFromFile();
}
// To create empty graph to transpose our values into,
// we need to clear out builder settings that would populate a new graph.
savedBuilder.fileHandle = null;
savedBuilder.nodes = 0;
savedBuilder.edges = 0;
// otherwise, everything the same, so just pass modified builder to constructor
// save the reference to this graph ( ready for the reversal method to use )
this.gPrime = new Graph(savedBuilder);
)
Once again. Two graph objects, with the gPrime in each referencing the other, is the goal.
Sequence is:
build g - - - populate g - - - reverse g into an empty graph with the same characteristics as g
So, here is the problem I don't quite understand.
If I assign g to gPrime.gPrime, either in the build after g us built or in the bottom of the constructor, I get an error message stating that gPrime is final. Eclipse indicates it's the first gPrime that is in question - - - which is true - - - it is final and has been assigned. But gPrime.gprime ( with the emphasis on the second gPrime ) has not been assigned yet. ( I searched the entire program. )
I also tried putting the assignment at the bottom of the reverse method. Same thing.
I also tried g.gPrime.gPrime in the builder. Same thing.
It's almost as if the compiler is confused about which gPrime is receiving the assignment.
I am sure there is something I am not seeing or understanding - - - but - - - don't know how to make this happen.
I can make this work if I take out the final, but I am trying to get to immutable.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您需要不可变的循环依赖项。您必须实现它,以便当您
构建A
(在A的构造函数中)时,您必须使用调用
B
的构造函数
>这个。下面是Builders的代码(你必须确保整个构建过程不会从当前线程中逃逸):
B类:
如何使用它:
^< br>
^
^
如果您想要单个类和两个循环依赖的对象):
You need circular dependencies that are immutable. You have to implement it so that when you
Build A
(in the constructor of A) you have to call theconstructor
ofB
withthis
.Here is the code with Builders (You have to make sure that the whole building process does not escape from the current thread):
Class B:
How to use it:
^
^
^
If you want to have single class and two objects in circular dependency):
我认为我的答案只是 Op De Cirkel 答案的简化版本,根据您的具体需求量身定制。这个想法是在构建器中拥有 gPrime 实例,因此在构造函数中,如果构建器有一个非 null gPrime,则使用它,否则构建它:
this.gPrime.gPrime = this
将不会可以在任何地方工作,因为 gPrime 是实例的最终字段,并且只能在声明时或在该实例的构造函数中初始化。this.gPrime.gPrime = this
所做的是初始化其他实例的 Final 字段,这违反了gPrime
的“最终性”I think my answer is just a simplified version of Op De Cirkel's answer, tailored to your specific needs. The idea is to have the gPrime instance in the builder, so in the constructor, if the builder has a non-null gPrime, use it, otherwise build it:
this.gPrime.gPrime = this
will not work anywhere becausegPrime
is a instance final field and can only be initialized when declared or in constructor for that instance. Whatthis.gPrime.gPrime = this
is doing is initializing the final field for other instance, which violates the "finalness" ofgPrime
您无法初始化不可变的循环结构。您可以通过将
gPrime
更改为非final
来使其有效地不可变,并确保始终在使用之前将其设置为一个值。感谢 Op De Cirkel 的回答:
您可以使用两个构建器,或者构建器功能中的开关,其中您有一个构建器保存对当前正在构建的 Graph 对象的引用:
用法示例:
You can't initialize an immutable circular structure.You can have it effectively immutable by changing
gPrime
to not befinal
, and making sure you always set it to a value before it is used.Thanks to Op De Cirkel's answer:
You can use two builders, or a switch in the functionality of your builder, where you have a builder that holds a reference to the Graph object that you are currently constructing:
Usage example: