如何将一个ArrayList的内容移动到另一个? [英] How to move contents of one ArrayList to another?

查看:197
本文介绍了如何将一个ArrayList的内容移动到另一个?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有一个ArrayList的全部内容移动到ArrayList的另一个实例在O方式(1)?

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).

例如:

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)

更妙的是,有一个的ArrayList#swapContents(ArrayList的)方法?

进一步的解释和用例

的进一步说明的1:'一'和'b'的引用必须不进行交换。我不是在寻找 TMP =一个; A = B; B = TMP; 类型的解决方案

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.

进一步说明的2:操作必须〜O(1)时间

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);
    }
}

这是我们希望避免复印件(以提高速度和减少内存使用)的通知。关键的一点是,被叫方必须失去修改能力(现在封装)的ArrayList

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.

推荐答案

这应该这样做:

ArrayList<String> a = new ArrayList<>(Arrays.asList("A", "B", "C"));
ArrayList<String> b = a;
a = new ArrayList<>();

从概念上讲, A 现在是空的, B 包含的 A 前载。有一个单一的任务,也没有复制数据,这是你能做到这一点是最快的。这是否满足您的要求,或做你真正想要 A 来仍引用同一阵列除了给定的数组,现在应该是空的?

Conceptually speaking, a is now empty and b contains what a contained before. There was a single assignment and no copying of data, which is about the fastest you can do it. Does that satisfy your requirement, or do you actually want a to still reference the same array except that the given array should now be empty?

<罢工我不相信,在C ++中移动操作的时间复杂度为O(1)无论是。它也谨慎地指出,因为在Java类中使用引用,有在这些语言的对象从来没有任何隐含的副本问题移动语义解决没有,从来没有在Java中存在(见FredOverflow答案:<一href=\"http://stackoverflow.com/questions/9498381/c-rvalue-references-and-move-semantics?answertab=votes#tab-top\">C++右值引用和移动语义)

I don't believe that in C++ the time complexity for the move operation is O(1) either. It's also prudent to point out that "because classes in Java use reference semantics, there are never any implicit copies of objects in those languages. The problem move semantics solve does not and has never existed in Java." (see the answer by FredOverflow: C++ Rvalue references and move semantics)

是否有一个ArrayList的整个内容转移到另一个的ArrayList的方式,使得仅在背衬阵列基准从一个传递到其他(即,使得元件不复制逐个)。

Is there a way to move the entire contents of an ArrayList to another ArrayList so that only the reference to the backing array is passed from one to the other (i.e., so that elements are not copied one by one).

鉴于上述说法,那么如果从阵列 A 来阵列 B 在Java中,两个数组复制的东西将引用相同的数据。所有你在C移动语义++做的是保存所需要创建,以使这种复制的临时对象:

Given the above statement, then if you copy something from array a to array b in Java, both arrays will reference the same data. All that you do with move semantics in C++ is that you save the temporary object which needs to be created in order to make such a copy:

X foo();
X x;
// perhaps use x in various ways
x = foo();

最后一个作用:

destructs the resource held by x,
clones the resource from the temporary returned by foo,
destructs the temporary and thereby releases its resource. 

移动语义的作用:

Move semantics does:

swap resource pointers (handles) between x and the temporary,
temporary's destructor destruct x's original resource.

您救一个自毁,但只能在C ++中......上述问题不会在Java中存在!看到这篇文章,详细了解移动语义: http://thbecker.net/articles/rvalue_references/section_02 html的

You save one destruct, but only in C++... the above problem does not exist in Java! See this article for more details on move semantics: http://thbecker.net/articles/rvalue_references/section_02.html

这篇关于如何将一个ArrayList的内容移动到另一个?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆