New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Can a PriorityQueue implement Cloneable? #124
Comments
Cloning is quite broken, but a pull request with a Cloneable implementation would be great :). |
If you only need some way to copy a collection and not something passing public HeapPriorityQueue(HeapPriorityQueue<? super K> queue) {
// do copy here
} PS: When you mask exceptions, be sure to pass the original exception to preserve the stack trace! |
Yeah, you're right. A copy constructor is a better idea. Though many fastutil classes actually implement clone(). |
thats fair @incaseoftrouble - my work in progress for the PR for Cloneable is at Final decision? |
The point is that we don't want to reconstruct the queue by re-inserting every item - a copy of the (e.g.) heap is sufficient. Can the constructor be engineered in such a fashion? |
I think something like the following should work, with little modification to the code. Basically you take your public MyHeapPriorityQueue(Collection<? super K> elements) {
if (queue instanceof MyHeapPriorityQueue) {
MyHeapPriorityQueue other = (MyHeapPriorityQueue) queue;
this.heap = new CollectionImplementingTheHeap(other.heap); // or other.heap.clone() if necessary
this.comparator = other.comparator; // etc.
} else if (elements instanceof SortedSet) {
this.heap = new CollectionImplementingTheHeap();
this.comparator = elements.comparator
addAll(queue);
} else {
// addAll()
}
} EDIT: Or what @vigna said. He's the maintainer, after all ;) |
So, following the fastutil custom implementations can be Cloneable. Interfaces don't. So you should make (for coherence) the five implementation of PriorityQueue Cloneable, implement clone() and add some unit test for each clone() method. Also, super.clone() will do shallow copying, so you just need to clone the backing array—the rest will be done for you. |
I gave a look at this:
I'm beginning to favour trying instead the constructor suggestion of @incaseoftrouble - however, note that a fastutils PriorityQueue doesn't extend Collection, so the constructor would look like: public HeapPriorityQueue(PriorityQueue<? super K> q) {
if (! q instanceof HeapPriorityQueue) throw IllegalArgumentException();
this.size = q.size;
this.heap = q.heap.clone();
//etc
} |
Depends on whether you want a shallow or deep copy.
True. But this can be moved to a static utility class.
Why? This can be done via wrapping, right? Or do you mean copying a SynchronizedQueue?
Cloning should not be put in the interface I think, simply for consistency.
That's fine. I think the constructor should also work with different PriorityQueues, simply calling addAll(). |
|
We had a use-case to make a copy of a PriorityQueue. Short of serialization and deserialization, the option was to make a sub-class that could handle cloneing:
The text was updated successfully, but these errors were encountered: