본문으로 바로가기

ArrayList<DataClass> 를 DeepCopy 하는 법

category Studies/Android 2022. 6. 20. 16:06

자주 저지르기 쉬운 실수에 대해 기록하고자 한다.

 

알아두어야 고생하지 않는 종류의 실수기 때문에 기록하고자 한다.

val instance1 = arrayListOf(
		MyData(1,2),
                 MyData(3,4)
                )

val instance2 = instance1 // 얕은 복사.

instance2.forEach{ it->
	it.id = 100
}

println(instance1.get(0).id) //100

* 위에서 하고자 하는 일은 instance2 에서 instance1을 카피해 instance1에 영향이 없도록 instance2를 수정하여 사용하는 일읻다.

 

이 경우 주의할 점은 다음과 같다.

1) 리스트를 카피 한다.

2) forEach 문 사용 시 데이터클래스를 copy() 하여 수정한다.

 

위의 사례에서는 두가지 다 하지 않았기 때문에, instace1 과 instance2 는 같은 메모리에 할당되어 instance2 에서의 변화는 instance1 에도 영향을 끼친다.

 

올바른 사례는 다음과 같다.

val instance1 = arrayListOf(
		MyData(1,2),
                 MyData(3,4)
                )

val instance2 = arrayListOf()
instance2.addAll(instance1)

instance2.forEachIndexed { index, MyData ->
    val data = MyData.copy()  //깊은 복사
    data.id = 100
    instance2.set(index,data)
}

println(instance1.get(0).id) //1
println(instance2.get(0).id) //100

ArrayList가 올바르게 딥 카피 된 것이다.

 

*특이사항

removeIf() 로 리스트의 원소를 삭제하려는 경우 데이터 클래스를 카피하지 않아도 상관없지만,

위처럼 forEach로 ArrayList를 수정하는 경우는 카피해줘야 함.

val instance1 = arrayListOf(
		MyData(1,2),
                 MyData(400,300)
                )

val instance2 = arrayListOf()
instance2.addAll(instance1)

instance2.removeIf { it.id > 100 }

println(instance1.size) // 2
println(instance2.size) // 1

instance2.forEachIndexed { index, MyData ->
    val data = MyData.copy()  //깊은 복사
    data.id = -100
    instance2.set(index,data)
}

println(instance1.get(0).id) // 1
println(instance2.get(0).id) // -100