美文网首页
List中对值的改变影响了另一个List的值

List中对值的改变影响了另一个List的值

作者: maoai_xianyu | 来源:发表于2020-12-16 21:30 被阅读0次

    项目开发中,将多个对象(实体类)放到集合中,遇到一个List A 集合中,把List A 集合数据复制到另外的一个List B集合中,当修改新的List B集合的数据,旧的List A 集合也跟着修改了。


    问题描述

    1. 在内存中创建 List A 和 List B 在内存中会开辟空间
    2. List A集合中添加的对象,在内存也开辟空间
    3. 将List A集合的数据添加到 List B集合中,两个集合是不相等的,但是集合中的对象都指向的同一个,所以修改List B集合中的对象,List A 的集合也就改变了
    4. 方案:使List B 中对象 和 List A 中的对象不一样。可以达到改变 List B 集合中的对象,而不影响 List A 集合的数据

    解决方案

    • 先创建实体类对象
    定义实体类
    public class TestList {
            static class P implements Cloneable {
            public P(int id, String name) {
                this.id = id;
                this.name = name;
            }
    
            int id;
            String name;
    
            @Override
            public String toString() {
                return "P{" +
                        "id=" + id +
                        ", name='" + name + '\'' +
                        '}';
            }
    
            @Override
            protected P clone() throws CloneNotSupportedException {
                return (P) super.clone();
            }
        }
    
        static class PP implements Serializable {
    
            public PP(int id, String name) {
                this.id = id;
                this.name = name;
            }
    
            int id;
            String name;
    
            @Override
            public String toString() {
                return "P{" +
                        "id=" + id +
                        ", name='" + name + '\'' +
                        '}';
            }
        }
    
    • 使用深拷贝,让实体类实现 Cloneable , 同时复写 object 的 clone() 方法
    public class TestList {
         public static void main(String[] args) {
            modelCopy();
        }
    
        private static void modelCopy() {
            ArrayList<P> list = new ArrayList<>();
            for (int i = 0; i < 10; i++) {
                list.add(new P(i, "i " + i));
            }
    
            ArrayList<P> listNew = new ArrayList<>();
            for (P p : list) {
                try {
                    listNew.add(p.clone());
                } catch (CloneNotSupportedException e) {
                    e.printStackTrace();
                }
            }
    
            for (int i = 0; i < listNew.size(); i++) {
                if (listNew.get(i).id == 1) {
                    P p1 = listNew.get(i);
                    p1.name = "zhang";
                    break;
                }
            }
    
            System.out.println(" 旧 "+list);
            System.out.println(" 新 "+listNew);
        }
    }
    
    • 不使用深拷贝:使用ArrayList 中的 clone() 复制一个新的 ArrayList 集合, 但是需要对修改对象进行重新设值,再赋值到当期位置的对象。
    public class TestList {
    
        public static void main(String[] args) {
            collDeepNew();
        }
    
      private static void collDeepNew() {
            System.out.println("循环赋值 创建新的对象 -------");
    
            ArrayList<PP> listP = new ArrayList<>();
            for (int i = 0; i < 10; i++) {
                listP.add(new PP(i, "i " + i));
            }
    
            ArrayList<PP> newListP = (ArrayList<PP>) listP.clone();
            if (newListP != null) {
                for (int i = 0; i < newListP.size(); i++) {
                    if (i == 1) {
                        PP pp = new PP(newListP.get(i).id, newListP.get(i).name);
                        pp.name = "zhang";
                        newListP.set(i, pp);
                        break;
                    }
                }
                System.out.println("循环赋值 原list值:" + listP);
                System.out.println("循环赋值 新list值:" + newListP);
            }
            System.out.println("---------------------");
    
        }
    }
    
    • 不使用深拷贝:使用读流文件
    public class TestList {
    
        public static void main(String[] args) {
            collDeepNew();
        }
    
      private static void collDeep() {
            System.out.println("DeepCopyUtil -------- 深拷贝 需要实体类继承 Serializable");
    
            List<PP> listP = new ArrayList<>();
            for (int i = 0; i < 10; i++) {
                listP.add(new PP(i, "i " + i));
            }
    
            //list深度拷贝
            List<PP> newListP = DeepCopyUtil.deepCopy(listP);
            if (newListP != null) {
                for (int i = 0; i < newListP.size(); i++) {
                    if (i == 1) {
                        newListP.get(i).name = "zhang";
                        break;
                    }
                }
                System.out.println("原list值:" + listP);
                System.out.println("新list值:" + newListP);
            }
    
        }
    }
    
    public class DeepCopyUtil {
    
        /**
         * List深拷贝 条件:需要model实现Serializable
         */
        public static <T> List<T> deepCopy(List<T> t) {
            try {
                // 写入字节流
                ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
                ObjectOutputStream out = new ObjectOutputStream(byteOut);
                out.writeObject(t);
    
                ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());
                ObjectInputStream in = new ObjectInputStream(byteIn);
                return (List<T>) in.readObject();
            } catch (IOException | ClassNotFoundException e) {
                e.printStackTrace();
                return null;
            }
        }
    }
    

    总结

    相关文章

      网友评论

          本文标题:List中对值的改变影响了另一个List的值

          本文链接:https://www.haomeiwen.com/subject/rwuogktx.html