Is there a way to move the entire contents of an ArrayList to another instance of ArrayList in O(1)?
I.e.: only the reference to the backing array is passed from one instance to the other (elements are not copied one by one).
For example:
ArrayList<String> a = new ArrayList<>(Arrays.asList("A", "B", "C"));
ArrayList<String> b = new ArrayList<>();
a.moveContentsTo(b);
// 'a' is now empty, while 'b' contains everything that 'a' did before and 'a != b'
// It is desired that the 'moveContentsTo' method is O(1)
Even better, is there an ArrayList#swapContents(ArrayList)
method?
Further explanation and use-case:
Further explanation 1: the references of 'a' and 'b' must not be exchanged. I am not looking for tmp = a; a = b; b = tmp;
type of solutions.
Further explanation 2: The operation must be ~O(1) in time.
The use-case: This is useful when an object wants to encapsulate a list constructed outside:
public class A {
private ArrayList<String> items = new ArrayList<>();
/**
* This method takes the sole ownership of the contents. Whoever
* passed the list from the outside will not be able to modify
* contents of 'this.items' from outside the class.
*/
public AnImmutableObject(ArrayList<String> items) {
if (items != null) {
items.moveContentsTo(this.items);
}
}
/**
* Other collections that do not provide the 'move' functionality
* must be copied. If we just stored the reference to 'items' we
* would break encapsulation as whoever called the constructor
* still have write capabilities to the collection.
*/
public A(Collection<String> items) {
if (items != null) {
this.items.addAll(items);
}
}
public List<String> getItems() {
return Collections.unmodifiableList(items);
}
}
Notice that we want to avoid making a copy (to increase speed and decrease memory usage). The crucial bit is that the callee must lose the ability to modify the (now encapsulated) ArrayList
.
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…