본문 바로가기
Jave & Kotlin

Kotlin - indexOf()를 통한 Data Class와 Class 특성 알아보기

by devLog by Ronnie's 2023. 1. 24.

개발을 하던 도중 indexOf()를 활용하여 전달 된 파라미터 값과 일치하는 리스트 값의 인덱스 번호를 반환해줘야 하는 경우가 생겼다.

List안에는 일치하는 값이 있음에도 불구하고 indexOf() 함수를 활용하여 값을 찾으려고 하는데 반환 된 값이 -1로 떨어지는 것이었다. 해당 케이스에 대한 원인과 해결 방안에 대해서 정리한다.

 

Kotlin - indexOf()를 통한 Data Class와 Class 특성 알아보기

 

Kotlin - indexOf()를 통한 Data Class와 Class 특성 알아보기

 

원인


다음과 같이 List 컬렉션에서는 indexOf() 함수를 제공한다. indexOf()는 해당 값이 존재하지 않으면 -1을 반환하고 존재한다면 해당 index 값을 리턴한다.

찾으려고 한 값은 dto 객체 내의 특정 필드의 값을 찾는 것이 었고 예시를 들면 다음과 같다.

 

val testList = listOf(TestDTO(“findValue1”), TestDTO(“findValue2”), TestDTO(“findValue3”))

testList.indexOf(TestDTO(“findValue1”))

 

이것이 정상 동작하면 결과는 0이 반환될 것이다. testList에 findValue1를 가지고 있는 인덱스값은 0번째이기 때문이다.

 

하지만 -1이 나왔다. 원인은 바로 Data Class 와 일반 Class의 차이에서 생기는 현상이었다.

 

다음과 같이 간단한 테스트 코드를 구현한다.

해당 테스트 케이스를 돌려보면 TestDTO에 대한 값은 잘 나오는데  Test2DTO의 결과값은 다 -1이 나오는 것을 확인할 수 있다.

해결 방법


위에서도 말했듯이 차이는 TestDTO는 Data Class로 선언되어 있고 Test2DTO는 일반 Class로 선언되어 있다.

 

그럼 여기서 이런 의문점이 생긴다. 둘의 차이가 뭐길래 Data Class는 인덱스 값이 정확히 나오고 Class는 나오지 않는지 말이다.

이거를 알기 위해서는 indexOf() 함수에 대해 정확히 알 필요가 있다.

 

 

만약 indexOf에서 비교하는 대상이 객체가 아닌 일반 String과 같은 타입을 파라미터로 넘긴다면 다음과 같은 현상은 발생하지 않는다.

여기에서는 indexOf로 넘기는 파라미터가 객체인 경우여서 발생하는 상황인데 객체를 넘기는 경우에는 해당 객체에서 구현되어 있는 equals()를 통해서 값을 비교해 있는지 없는지 판단하여 인덱스 값을 리턴하게 된다.

 

Data Class의 특성으로는 사용자가 구현해주지 않아도 내부적으로 toString() / equals() / hashCode() / copy() 를 자동으로 만들어준다. (당연 다르게 사용하고 싶다면 override를 통해 직접 구현도 가능하다. 직접 구현 시 직접 구현된 코드를 사용)

 

바로 이러한 특성때문에 Data Class인 TestDTO는 equals()를 통해 객체 비교를 하여 인덱스 값이 반환된 것이고 Test2DTO는 equals() 가 없기 때문에 안 나온 것이다.

 

다음과 같이 equals() 를 구현 후 다시 테스트를 돌려보면 결과값이 잘 나오는 것을 확인 할 수 있다.

 

댓글