问题
This question is an extension of this question.
I have a class similar to the following.
class HighlightableStructure {
private final HighlightableStructure NEXT;
HighlightableStructure(HighlightableStructure next) {
NEXT = next;
}
}
where a HighlightableStructure
points to the next structure to highlight.
Sometimes, these HighlightableStructure
s loop around and refer to a previous HighlightableStructure
, but not the first in the chain. Something like h_1 -> h_2 ->h_3 -> ... -> h_n -> h_2, where h_i is an instance of HighlightableStructure
.
Is there anyway I could construct something like this without reflection or losing immutability?
回答1:
One possible solution:
class HSequenceBuilder {
private long id = 0;
private final Map<Integer, H> map = new HashMap<Integer, H>();
static H create(int next) {
H h = new H(id, next, Collections.unmodifiableMap(map));
map.put(id, h);
id++;
return h;
}
static H create() {
create(id + 1);
}
}
class H {
private final id;
private final Map<Integer, H> map;
private final int next;
H(int id, int next, Map<Integer, H> map) {
this.id = id;
this.next = next;
this.map = map;
}
int getId() { return id; }
}
HSequenceBuilder builer = new HSequenceBuilder();
H h1 = builder.create(); // 1.
H h2 = builder.create(); // 2.
H h3 = builder.create(h2.getId()); // 3.
回答2:
The answer of the linked question is easily expandable to an arbitrary number of objects, if you have a way to specify the needed nodes at construction time, e.g.
final class CircularLinkedList<T> {
final CircularLinkedList<T> next;
final T value;
public CircularLinkedList(T firstValue, List<T> other) {
value = firstValue;
next = other.isEmpty()? this: new CircularLinkedList<>(this, 0, other);
}
private CircularLinkedList(CircularLinkedList<T> head, int pos, List<T> values) {
value = values.get(pos);
next = ++pos == values.size()? head: new CircularLinkedList<>(head, pos, values);
}
@Override
public String toString() {
StringJoiner sj = new StringJoiner(", ").add(value.toString());
for(CircularLinkedList<T> node = next; node != this; node = node.next)
sj.add(node.value.toString());
return sj.toString();
}
}
Which you can use like
CircularLinkedList<String> cll
= new CircularLinkedList<>("first", Arrays.asList("second", "third", "fourth"));
System.out.println(cll);
// demonstrate the wrap-around:
for(int i = 0; i < 10; i++, cll = cll.next) {
System.out.print(cll.value+" .. ");
}
System.out.println(cll.value);
回答3:
You’ve got a linked list, which requires its nodes to be mutable. You can have mutable object but still get very similar benefits to immutability if you publish safe copies of your nodes.
Hide you nodes inside a containing object and when your API must return a node, return a copy of it instead, or even a copy of the entire structure as required.
来源:https://stackoverflow.com/questions/57137454/any-nice-way-to-make-a-chain-of-immutable-objects-loop-around