개발 일지/Spring

Service 로직에서 List를 다룰 때 발생하는 index 문제 해결

미숫가루설탕많이 2023. 6. 27. 23:02

프로젝트에서 맡은 이력서 CRUD 작업의 기본 로직을 다 만들어 두고 추가로 수정할 부분이 없나 하고 찾아보다가 문제를 하나 발견했다. Postman으로 여러 데이터를 입력해보고 테스트를 진행했을 때는 발생했던 오류가 아니어서 작업하면서는 찾지 못했던 것 같다.

 

기존에 작성했던 코드는 다음과 같다.

 

이력서를 수정하는 코드 안에 포함된 로직이다. 이 로직을 추가한 이유는 사용자가 이력서를 수정할 때, 기존의 이력서에는 경력사항이나 프로젝트 등이 들어가 있었지만 해당 데이터들을 지우거나 수정한 경우에 수정된 이력서에 들어가 있는 경력 사항 등만 두고 기존의 데이터는 지우려고 했기 때문이다.

 

테스트를 할 때는 저 로직에서 발생하는 예외상황을 생각하지 못했었는데, 위 remove에서 밑줄 그인 부분이 신경쓰여서 보다가 알게 되었다.

친절한 갓텔리제이..

 

리스트에서 요소를 제거하는 동안에 인덱스 범위를 벗어나는 문제가 발생할 수 있어..! 라고 친절하게 얘기해주고 있었다.

 

문제가 발생하는 이유는 findCv.getProjects().remove(i) 를 호출할 때마다 findCv.getProjects()의 크기가 줄어들기 때문이다. 즉, 리스트의 크기가 변하면서 인덱스의 유효성이 변경되기 때문에 IndexOutOfBoundsException이 발생하는 것이다.

 

따라서 다음과 같이 요소를 제거할 때 역순으로 제거하게끔 for문의 조건을 바꿔줬다. 이렇게 하면 리스트의 크기가 동적으로 변하더라도 에러 없이 잘 제거될 것이다.

또 노란줄?

 

 

 

 

추가

 

아니 잘 적용한 것 같았는데 이번에는 for문에 노란 밑줄이 생겼다.

 

더 좋은 코드를 알려준다고..?

 

오.. subList를 활용해서 범위를 지정한 후에 clear() 하니까 불필요하게 for문으로 반복할 필요도 없고 가독성도 더 좋아진 것같다.

 

String의 substring()이랑 비슷하게 생겨서 리스트의 저 범위 부분만 따로 떼어내는 줄 알고 검색해봤는데, substring() 과는 달리 리스트의 일부(범위만큼)를 나타낸다고 한다. 그리고 그 일부를 변경하게 되면 기존의 리스트에도 영향을 주기 때문에 clear() 메서드를 호출하면 해당 범위 만큼의 요소가 삭제되는 것이다.

 

이렇게 하나 또 배워갑니다 갓텔리제이..!