#1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
List<String> list1 = new ArrayList<String>();
        
list1.add("사과");
list1.add("딸기");
list1.add("키위");
list1.add("바나나");
 
List<String> list2 = list1;
System.out.println("list1 : " + list1);
System.out.println("list2 : " + list2);
 
System.out.println("list1 의 \"사과\" 제거 ");
list1.remove(0);
 
System.out.println("list1 : " + list1);
System.out.println("list2 : " + list2);
cs

1) list1에 사과, 딸기, 키위, 바나나 를 넣었다 (3~6 line)
2) list2에 list1을 넣어주었다 (8 line)
3) list1에서 사과(index : 0) 값을 제거 (13 line)
4) 사과 제거 전 list1, list2 출력 (9, 10 line)
5) list1에 담긴 사과 제거 후 list1, list2 출력 (15, 16 line)

 

위의 코드 실행시 결과는 어떻게 될까?

list1 의 사과 값만 제거 했으므로 list2 엔 사과 값이 존재하고, 출력될까?

 

결과는 다음과 같다. 

list1 에서 사과를 제거했는데 list2 의 사과도 제거되었다.

 

list2 에 list1을 대입한 게 아닌, list2가 list1 의 주소값을 참조하게 했기 때문이다.

List 는 참조형 이기 때문에 값자체가 아닌 주소값을 참조하므로 

#1과 같이 코딩시 위처럼 예상치 못한 결과가 나올 수 있다. (Map 및 Set 또한 마찬가지)

아래와 같이 addAll (List, Set), putAll (Map)을 사용하여 값 자체를 대입시켜 줄 수 있다.

 

 

#2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
List<String> list1 = new ArrayList<String>();
 
list1.add("사과");
list1.add("딸기");
list1.add("키위");
list1.add("바나나");
 
List<String> list2 = new ArrayList<String>();
list2.addAll(list1);
 
System.out.println("list1 : " + list1);
System.out.println("list2 : " + list2);
 
System.out.println("list1 의 \"사과\" 제거 ");
list1.remove(0);
 
System.out.println("list1 : " + list1);
System.out.println("list2 : " + list2);
cs

#1 코드에서 list2 의 선언 및 list1 의 값을 넣어주는 부분(8~9 line) 만 위와 같이 바꿔보았다.

 

결과는 다음과 같다.

#1과 달리 list2의 사과값이 제거되지 않았다.

 

#3 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
List<Map<StringString>> list1 = new ArrayList<Map<StringString>>();
 
Map<StringString> map1 = new HashMap<StringString>();
map1.put("과일""사과");
map1.put("동물""물고기");
map1.put("지역""서울");
 
Map<StringString> map2 = new HashMap<StringString>();
map2.put("과일""바나나");
map2.put("동물""호랑이");
map2.put("지역""부산");
 
list1.add(map1);
list1.add(map2);
 
List<Map<StringString>> list2 = new ArrayList<Map<StringString>>();
list2.addAll(list1);
 
System.out.println("조작전 list1 : " + list1);
System.out.println("조작전 list2 : " + list2);
System.out.println("=================================");
 
list1.get(0).remove("과일");
 
System.out.println("조작후 list1 : " + list1);
System.out.println("조작후 list2 : " + list2);
cs

1) map1 에 과일:사과, 동물:물고기, 지역:서울 값을 넣는다.

2) map2 에 과일:바나나, 동물:호랑이, 지역:부산 값을 넣는다.

3) list1 에 map1, map2 값을 넣는다.

4) list2 에 list1을 넣는다.

5) list1에 담긴 map1(list1.get(0))의 과일 값을 제거한다

6) 조작전 list1 과 조작 후 list1, list2 를 출력한다.

 

결과는 아래와 같다.

list2에 list1 을 addAll 로 넣어주었는데? 라고 생각할 수 있지만,

list1 이 갖고 있는 map1, map2 값 자체가 아닌 map1, map2 의 주소값만 list2 에 저장되었기 때문이다.

(#2에서 확인한 것 처럼 #3에서 역시, list2.remove(0) 으로 list2에 담겨있는 map1의 주소값을 제거할 경우 list1엔 영향을 주지 않는다)

 

#4

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
List<Map<StringString>> list1 = new ArrayList<Map<StringString>>();
 
Map<StringString> map1 = new HashMap<StringString>();
map1.put("과일""사과");
map1.put("동물""물고기");
map1.put("지역""서울");
 
Map<StringString> map2 = new HashMap<StringString>();
map2.put("과일""바나나");
map2.put("동물""호랑이");
map2.put("지역""부산");
 
list1.add(map1);
list1.add(map2);
 
List<Map<StringString>> list2 = new ArrayList<Map<StringString>>();
        
for(Map<StringString> m : list1) {
    Map<StringString> map3 = new HashMap<StringString>();
    map3.putAll(m);
    list2.add(map3);
}
 
System.out.println("조작전 list1 : " + list1);
System.out.println("조작전 list2 : " + list2);
System.out.println("=================================");
 
map2.remove("과일");
 
System.out.println("조작후 list1 : " + list1);
System.out.println("조작후 list2 : " + list2);
cs

#3 코드에서 list2 의 선언 및 list1 의 값을 넣어주는 부분(18~21 line) 만 위와 같이 바꿔보았다.

 

결과는 다음과 같다.

 

* 2중 for문 및 iterator 를 돌려 map 내의 값을 직접 꺼내 map 에 직접 넣어준 후 list 에 add 를 해줘도 된다.

* map 이 아닌 VO의 경우 clone 을 사용하여 vo 값 자체를 복사한 후, list에 넣어 줄 수도 있다.

 

※ deep copy , shallow copy 에 대한 예제와 설명이 정리되어있는 글

https://howtodoinjava.com/java/collections/arraylist/arraylist-clone-deep-copy/

 

※ 참조형 같으면서 기본형 같은 String 자료형에 대한 설명이 잘 되어있는 좋은 글

https://brunch.co.kr/@kd4/1

반응형

+ Recent posts