힝구힝구
233
2021-05-28 10:29:18 작성 2021-05-28 10:35:29 수정됨
4
144

java arrayList의 clear와 new 로 할당했을 때 차이점


안녕하세요, 작업하다가 clear를 사용했었는데 값이 안나오던 친구가 new로 재할당 해주니까 제대로 나와서

차이점이 뭔지 알아보려고했는데, 도저히 모르겠어서 질문드립니다.

먼저 코드는 간단하게 다음과 같습니다.

@Override
public List < CloudShoppingHisVO > selectViewGoodsList(ParamMap viewGoodsMap) throws Exception {
    List < CloudShoppingHisVO > ShoppingHisList = mypageDAO.selectViewGoodsList(viewGoodsMap);
    //리스트 select해주는 쿼리 (retrun 되는 친구임)
    ParamMap param = new ParamMap();
    ParamMap imageMap = new ParamMap();
    List < VodImageVO > titleImageList = new ArrayList < VodImageVO > ();
    List < VodImageVO > posterImageList = new ArrayList < VodImageVO > ();

    //resturn 될 리스트의 속성인 titleImageList객체 생성

    for (CloudShoppingHisVO shoppingHisVO: ShoppingHisList) {
        ... (코드생략)

        List < VodImageVO > imageList = displayDAO.selectVodImageList(param);

        titleImageList.clear();
        posterImageList.clear();

        //넣기 전 클리어 해주기, (for문 돌면서 이전에 있던 값 없애고 넣어주기위함)

        for (VodImageVO image: imageList) {
            String type = image.getType();

            if ("10".equals(type)) {
                titleImageList.add(image);
            } else if ("20".equals(type)) {
                posterImageList.add(image);
            }

        }
        //위에서 add 해준 titleImageList를 foreach문 도는 VO에 세팅해준다.
        shoppingHisVO.setTitleImageList(titleImageList);
        shoppingHisVO.setPosterImageList(posterImageList);

    }

    return ShoppingHisList;
}

일단 clear를 사용한코드는 이렇구요. 디버깅 해보면 값이 잘 들어가는것도 확인이 됩니다.

그런데 마지막 return에 BP를 걸고 보면..


이렇게 비어있습니다... 그래서, clear 함수 대신 new로 재생성 해주니까 잘 되더라구요..?

근데 왜 이렇게 되는건지 모르겠습니다.

shoppingHisVO 라는 객체에 직접 할당해주고, VO에 titleImageList객체가 다 들어갔는데?

foreach문을 도는 shoppinHisList를 확인해보면 해당 내용이 사라져있고..

근데 그게 clear대신 new를 쓰면 또 정상적으로 들어간다..

new를 쓰면 clear보다 성능상으로 안좋지않나요? 그래서 clear를 쓴건데..

왜이러는걸까요 ㅠㅠ 너무궁금합니다

0
  • 답변 4

  • ReuNyo
    296
    2021-05-28 10:54:25

    디버깅 해서 값이 잘 들어 간다는 게 반복문이 제일 마지막에 수행되었을 때의 List의 내용물인가요?

    아니라면 12번째 라인 반복문이 마지막으로 수행할 때 33번째 라인에서 breakpoint로 titleImageList 값이 어떤지 확인해보세요.

    코드 내용을 보았을 때 7, 8번째 라인에 생성한 List들에만 요소들을 add해주고 clear해주는데

    그러면 반복문을 돌면서 여러 shoppingHisVO 들은 전부 동일한 List만 바라보게 됨으로 제일 마지막 반복문 때 clear후 넣어준 값이 없으면 빈 List를 보여주는 게 맞아 보이네요.

    디버깅을 하면서 차근차근 List 내의 데이터가 어떻게 변화하는지 확인해 보는 것이 좋습니다.

  • 힝구힝구
    233
    2021-06-03 09:56:47

    ReuNyo


    답변 감사합니다.  그런데 질문이 있는데요,

    33번, 34번 라인까지 봤을 때는 shopingHisVO에 정상적으로 세팅이 되고, 안에 있는 데이터도 정상적으로 들어옵니다.

    그런데 for문이 끝나고 나서 shoppingHisList를 확인해보면 비어있습니다.

    clear를 사용한다면 shopingHisList의 각 인덱스의 고유한 titleImageList에 세팅을 해주는게 아닌가요?

    그러니까.. 7,8번 라인에서 생성한 List 하나만 가지고

    채워넣고, 비워주고, 채워넣고, 비워주고

    이 때 채워주는 건 shoppingHisList의 각 인덱스가 가지고 있는 메모리에 저장되는거고..

    이런게 아니라는 말씀이신거죠?

  • ReuNyo
    296
    2021-06-03 10:33:12

    소스상으로 보았을 땐 ShoppingHisList가 비어있는 건 이상하네요.

    정말 ShoppingHisList 내에 요소가 존재하다 사라지는 거면 어느 순간에 리스트가 비워지는지 디버깅 해보셔야 할 것 같네요.

    그리고 말씀하신 것처럼 7,8번 라인에서 생성한 List 하나 가지고 채워 넣고 비워주고 하기 때문에

    하나의 메모리 주소만 바라보게 되겠죠? 그러면 33, 34라인 setter에서 반복문 도는 VO들은 동일한 주소의 List만 세팅해주기 때문에 다른 곳에서 List 데이터를 변경하면 세팅된 List들이 바라보는 데이터들도 변경이 되어버리죠.

    예를 들어 A라는 사람과 B라는 사람이 동일한 집에서 동거하는 중인데 A가 집에 새로운 TV나 냉장고 등을 들여다 놓으면 B라는 사람이 집에 들어왔을 경우 새로운 가구들이 존재하게 되는 거죠.

    반대로 B가 집에 있는 가구들을 전부 처분해버리면 A가 집에 들어왔을 때 아무것도 없는 것이구요.

    그러므로 각각 다른 VO에 새로운 List로 할당 해주셔야 원하는 결과를 얻으실 수 있으실 것 같네요.

  • 힝구힝구
    233
    2021-06-04 13:16:12

    ReuNyo


    아.. 그렇군요 상세한 설명 정말 감사합니다! 크게 배워가네요

  • 로그인을 하시면 답변을 등록할 수 있습니다.