復制ArrayList的四種方式


使用構造函數

ArrayList有個構造函數,可以傳入一個集合:

 1 public ArrayList(Collection<? extends E> c) {
 2     elementData = c.toArray();
 3     if ((size = elementData.length) != 0) {
 4         // c.toArray might (incorrectly) not return Object[] (see 6260652)
 5         if (elementData.getClass() != Object[].class)
 6             elementData = Arrays.copyOf(elementData, size, Object[].class);
 7     } else {
 8         // replace with empty array.
 9         this.elementData = EMPTY_ELEMENTDATA;
10     }
11 }

 

上面的代碼我們可以看出,底層實際上調用了Arrays.copyOf方法來對數組進行拷貝。這個拷貝調用了系統的native arraycopy方法,注意這里的拷貝是引用拷貝,而不是值的拷貝。這就意味着這如果拷貝之后對象的值發送了變化,源對象也會發生改變。

舉個例子:

    @Test
    public void withConstructor(){
        List<String> stringList=new ArrayList<>(Arrays.asList("a","b","c"));
        List<String> copyList = new ArrayList<>(stringList);
        copyList.set(0,"e");
        log.info("{}",stringList);
        log.info("{}",copyList);

        List<CustBook> objectList=new ArrayList<>(Arrays.asList(new CustBook("a"),new CustBook("b"),new CustBook("c")));
        List<CustBook> copyobjectList = new ArrayList<>(objectList);
        copyobjectList.get(0).setName("e");
        log.info("{}",objectList);
        log.info("{}",copyobjectList);
    }

 

運行結果:

22:58:39.001 [main] INFO com.flydean.CopyList - [a, b, c]
22:58:39.008 [main] INFO com.flydean.CopyList - [e, b, c]
22:58:39.009 [main] INFO com.flydean.CopyList - [CustBook(name=e), CustBook(name=b), CustBook(name=c)]
22:58:39.009 [main] INFO com.flydean.CopyList - [CustBook(name=e), CustBook(name=b), CustBook(name=c)]

 

我們看到對象的改變實際上改變了拷貝的源。而copyList.set(0,"e")實際上創建了一個新的String對象,並把它賦值到copyList的0位置。

使用addAll方法

List有一個addAll方法,我們可以使用這個方法來進行拷貝:

@Test
public void withAddAll(){

    List<CustBook> objectList=new ArrayList<>(Arrays.asList(new CustBook("a"),new CustBook("b"),new CustBook("c")));
    List<CustBook> copyobjectList = new ArrayList<>();
    copyobjectList.addAll(objectList);
    copyobjectList.get(0).setName("e");
    log.info("{}",objectList);
    log.info("{}",copyobjectList);
}

 

同樣的拷貝的是對象的引用。

使用Collections.copy

同樣的,使用Collections.copy也可以得到相同的效果,看下代碼:

    @Test
    public void withCopy(){
        List<CustBook> objectList=new ArrayList<>(Arrays.asList(new CustBook("a"),new CustBook("b"),new CustBook("c")));
        List<CustBook> copyobjectList = new ArrayList<>(Arrays.asList(new CustBook("d"),new CustBook("e"),new CustBook("f")));
        Collections.copy(copyobjectList, objectList);
        copyobjectList.get(0).setName("e");
        log.info("{}",objectList);
        log.info("{}",copyobjectList);
    }

使用stream

我們也可以使用java 8引入的stream來實現:

@Test
public void withStream(){

    List<CustBook> objectList=new ArrayList<>(Arrays.asList(new CustBook("a"),new CustBook("b"),new CustBook("c")));
    List<CustBook> copyobjectList=objectList.stream().collect(Collectors.toList());
    copyobjectList.get(0).setName("e");
    log.info("{}",objectList);
    log.info("{}",copyobjectList);

}
四種方法都是引用拷貝,在使用的時候要小心。

本文轉載自:https://www.cnblogs.com/flydean/p/how-to-copy-list.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM