#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<String, String>> list1 = new ArrayList<Map<String, String>>();
Map<String, String> map1 = new HashMap<String, String>();
map1.put("과일", "사과");
map1.put("동물", "물고기");
map1.put("지역", "서울");
Map<String, String> map2 = new HashMap<String, String>();
map2.put("과일", "바나나");
map2.put("동물", "호랑이");
map2.put("지역", "부산");
list1.add(map1);
list1.add(map2);
List<Map<String, String>> list2 = new ArrayList<Map<String, String>>();
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<String, String>> list1 = new ArrayList<Map<String, String>>();
Map<String, String> map1 = new HashMap<String, String>();
map1.put("과일", "사과");
map1.put("동물", "물고기");
map1.put("지역", "서울");
Map<String, String> map2 = new HashMap<String, String>();
map2.put("과일", "바나나");
map2.put("동물", "호랑이");
map2.put("지역", "부산");
list1.add(map1);
list1.add(map2);
List<Map<String, String>> list2 = new ArrayList<Map<String, String>>();
for(Map<String, String> m : list1) {
Map<String, String> map3 = new HashMap<String, String>();
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 자료형에 대한 설명이 잘 되어있는 좋은 글
'back > java' 카테고리의 다른 글
[Java] Collection Framework (0) | 2019.12.21 |
---|---|
Comparator, Comparable + Arrays.sort() 그리고 인터페이스.. (0) | 2019.09.02 |
LocalHost IP 가져오기 (0) | 2019.05.28 |
자바 컴파일 버전 Exception (Unsupported major.minor version 52.0) (0) | 2019.05.20 |
emoji 처리 (0) | 2019.04.26 |