Javalist深拷貝探究

一、為什麼需要深拷貝

對於Javalist,常常需要複製一個列表的內容到另外一個位置,這時候我們通常會使用List接口提供的copy方法進行複製。但是,使用copy方法複製出來的列表只是原列表的淺拷貝,即原列表和複製後的列表指向同一個內存地址,修改一個列表也會同時修改另一個列表。因此,在某些情況下,我們需要使用深拷貝來避免這種問題。

假設我們有一個List列表,其中存儲的是自定義的Student對象,我們需要將該列表中的所有Student對象複製一份到另一個列表中。 如果直接使用copy方法,只是對Student對象進行了淺拷貝,如果我們在後面修改一個列表中的Student對象屬性值,則另一個列表中的同一個對象的屬性值也會同時修改,這樣就會產生很多難以預測的問題。而使用深拷貝,則可以解決這個問題。

    /**
     * 聲明Student類,包含一個int類型的id屬性以及一個String類型的name屬性
     */
    private static class Student{
        private int id;
        private String name;
        //構造函數
        public Student(int id, String name) {
            this.id = id;
            this.name = name;
        }
        //getter和setter方法
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
    }

    public static void main(String[] args){
        //創建一個List存儲Student對象
        List studentList = new ArrayList();
        studentList.add(new Student(1, "張三"));
        studentList.add(new Student(2, "李四"));
        //使用copy方法進行淺拷貝
        List copyList = new ArrayList(studentList);
        //修改原列表第一個元素的name值
        studentList.get(0).setName("王五");
        System.out.println(studentList.get(0).getName());//輸出:王五
        System.out.println(copyList.get(0).getName());//輸出:王五
    }

二、淺拷貝與深拷貝的區別

從例子中可以看出,使用copy方法只是對Student對象進行了淺拷貝。那麼什麼是淺拷貝,什麼是深拷貝呢?

淺拷貝指的是拷貝一個對象,實際上只是拷貝了對象的引用(地址),新對象和原對象指向同一個內存地址。這樣,在操作新對象時,原對象也會同時受到影響。而深拷貝則是將原對象的所有屬性都複製到新對象中,並在堆內存中開闢新的空間存放新對象,新對象和原對象互不影響。

三、實現Javalist深拷貝

Javalist的深拷貝,可以通過以下幾種方式:

1. Java8的stream流實現深拷貝

使用Java8新特性的stream流實現深拷貝,需要注意每個類需要實現接口Serializable,以便對象序列化。

    //方法1:使用Java8的stream流實現深拷貝
    List copyList1 = studentList.stream().map(student -> {
        Student s = new Student(student.getId(), student.getName());
        return s;
    }).collect(Collectors.toList());

2. 使用BeanUtils實現深拷貝

使用Apache Commons BeanUtils提供的BeanUtils.copyProperties()方法實現深拷貝,需要注意每個類需實現接口Cloneable。

    //方法2:使用BeanUtils實現深拷貝
    List copyList2 = new ArrayList();
    try {
        for (Student student : studentList) {
            Student newStudent = (Student) BeanUtils.cloneBean(student);
            copyList2.add(newStudent);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }

3. 使用序列化公共方法實現深拷貝

將對象序列化後再進行反序列化即可實現深拷貝,需要注意每個類必須實現Serializable接口。

    //方法3:使用序列化公共方法實現深拷貝
    List copyList3 = new ArrayList();
    try {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();//輸出流
        ObjectOutputStream oos = new ObjectOutputStream(bos);//對象輸出流
        oos.writeObject(studentList);//序列化
        oos.flush();
        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());//輸入流
        ObjectInputStream ois = new ObjectInputStream(bis);//對象輸入流
        copyList3 = (List) ois.readObject();//反序列化
    } catch (Exception e) {
        e.printStackTrace();
    }

四、小結

在需要進行列表複製時,我們有時會遇到淺拷貝會帶來的問題,因此需要使用深拷貝來解決這個問題。Java8的stream流、BeanUtils以及序列化都是實現Javalist深拷貝的有效方式。

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/185324.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-11-26 12:17
下一篇 2024-11-26 12:18

相關推薦

  • Javalist取差集操作詳解

    在Java編程中,javalist取差集操作是非常常見和實用的一個操作。具體來說,這個操作是指從一個列表中去掉另一個列表中的元素,即找到兩個列表不同的部分。 一、常用的javali…

    編程 2025-02-27
  • Javalist交集詳解

    一、Javalist交集概述 Javalist交集是指兩個或多個集合中共同擁有的元素。在Java中,我們可以使用Collections類的靜態方法intersection來獲取兩個…

    編程 2025-02-11
  • 詳解javalist差集

    一、什麼是javalist差集 在Java中,List是非常基礎的數據類型,而javalist差集是List的一種操作。它可以用來比較兩個List中的元素,返回一個只包含第一個Li…

    編程 2025-02-05
  • JAVAlist,javalist轉數組

    本文目錄一覽: 1、Java的List如何實現線程安全? 2、java中list後面加是什麼意思? 3、java list集合什麼意思 Java的List如何實現線程安全? Jav…

    編程 2025-01-20
  • JavaList長度

    Java中提供了很多數據結構以及對應的方法,其中JavaList便是其中之一。JavaList提供了很多方便的方法,其中有一個非常基礎的方法——獲取List的長度,即List中元素…

    編程 2025-01-07
  • JavaList篩選詳解

    一、JavaList 簡介 JavaList 是一種常見的數據結構,它是一個有序的集合,可以存儲重複的元素。JavaList 是 Java API 中最為常用的集合之一,可以根據索…

    編程 2025-01-05
  • JavaList長度的重要性

    一、JavaList的長度表示數據量大小 JavaList是一種常用的數據結構,可以存儲許多數據。JavaList可以動態增加或減少元素,因此其長度可以顯示數據量的大小。在很多場景…

    編程 2025-01-03
  • JavaList的foreach函數詳解

    在Java程序中,我們經常會遇到需要操作一個列表(List)的情況。對於這種情況,Java語言提供了一種便捷的方式,那就是使用foreach函數來遍歷List中的元素。 一、for…

    編程 2024-12-26
  • javalist轉string數組

    一、從string轉char數組 在將javalist轉string數組之前,我們需要了解如何將string轉換為char數組。 char數組是一組unicode編碼字符序列,每個…

    編程 2024-12-26
  • Javalist刪除元素

    一、List概述 List是Java中集合框架中的一種接口,可以用來存放一組有序的元素,每一個元素都有一個對應的整數索引。List中的元素允許重複,所有元素都是以插入的先後順序保存…

    編程 2024-12-22

發表回復

登錄後才能評論