Copy the "pit" encountered by the List<Object> collection

Remember a pit that uses List<Object> to copy

The problem went through:

There is a requirement that the returned result group needs to be assembled into the format of Map<String, List<Object>>. The Map can be a string, which is no problem, and the latter is a collection. I reused a List<Object when assembling data. >As the basic collection, then traverse to create a new new collection and addAll the basic collection to the new collection, and then modify the new collection, and then ingeniously and fill it into the result Map.

The code is roughly like this:

Map<String,List<Object>> mapList = new HashMap<>();

List<Object> baseList = new ArrayList();//基础集合,当然这里面可能有基础数据



for(int i= 0;i<10;i++){

     List<Object> newList = new ArrayList();
     newList.addAll(baseList);

    newList.forEach(t->{

        //修改操作
        
    })

    mapList.put("1",newList);
}

Problems arise:

The data in the result set are all the same and are the last modified data

Wrote a small example:

  static class Student{

        private String username;

        private Integer age;

        public String getUsername() {
            return username;
        }

        public void setUsername(String username) {
            this.username = username;
        }

        public Integer getAge() {
            return age;
        }

        public void setAge(Integer age) {
            this.age = age;
        }


    }


    public static void main(String[] args) {

        List<Student> list = new ArrayList<>();

        for (int i=0;i<3;i++){
            Student stu = new Student();
            stu.setAge(i);
            stu.setUsername("Test"+i);
            list.add(stu);
        }

        List<Student> list1 = new ArrayList<>();
        list1.addAll(list);

        list.forEach(t->{
            log.info("集合list:{}",JSON.toJSON(t));
        });

        list1.forEach(t1->{
            log.info("集合list1:{}",JSON.toJSON(t1));
        });

        list1.forEach(t->{
            if (t.getUsername().equals("Test0")){
                t.setAge(99);
            }
        });

        log.info("========================================");

        list.forEach(t->{
            log.info("集合list:{}", JSON.toJSON(t));
        });

        list1.forEach(t1->{
            log.info("集合list1:{}",JSON.toJSON(t1));
        });

      
    }

Print result: Objects in both collections are changed

Troubleshooting:

At the beginning, I thought that there should be no problem with filling a new collection. It was very strange. After looking at the data carefully, I found that the data in the collection was the same and it was the last data. I found that the collection was overwritten, but considering that it is The new collection for new.

The first thing to consider is whether the addAll() method only copied the address of the collection, and then replaced it with circular filling. It still doesn’t work. After consulting the information, I found that addAll() is a new collection to fill.

After debugging, it is found that the addresses of objects in the collection are consistent. . . . . suddenly realized

result:

        When copying a collection, you should first copy the object elements in it to the new collection. Otherwise, it means that all the object addresses in the collection point to one, so of course all changes will be changed together. . . .

You can use this method in the hutool package for object copying:

BeanUtil.copyProperties("source object", "target object");

It is wrong to make such a low-level mistake, let's learn a lot of wisdom! ! ! !

Guess you like

Origin blog.csdn.net/qq_37764320/article/details/127501129