인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

인프런 커뮤니티 질문&답변

김재훈님의 프로필 이미지

작성한 질문수

나도코딩의 자바 기본편 - 풀코스 (20시간)

Iterator (전반전)

Iterator 문의

작성

·

46

0

 안녕하세요 ! Iterator 강좌 수강 후 궁금한 점이 있어 질문드립니다.

 

List<String> list = new ArrayList<>();
        list.add("유재석");
        list.add("(알 수 없음)");
        list.add("김종국");
        list.add("(알 수 없음)");
        list.add("강호동");
        list.add("(알 수 없음)");
        list.add("박명수");
        list.add("(알 수 없음)");
        list.add("조세호");

Iterator<String> it = list.iterator();

우선, 강좌와 동일하게 해당 조건에서 실행할 때

 

it = list.iterator();
while (it.hasNext()) {
    String s = it.next();
    if (s.contains("(알 수 없음)")) {
        it.remove(); // 삭제
    }
}
it = list.iterator();
while (it.hasNext()) {
    if (it.next().contains("(알 수 없음)")) {
        it.remove(); // 삭제
    }
}

위 코드와 아래 코드가 동일하게 동작하는 것 같은데, 코드의 가독성을 위해 String s 를 따로 선언해주는 것이 맞는지 궁금합니다 !

 

또한 추가적으로,

it = list.iterator();
while (it.hasNext()) {
    String s = it.next();
    if (s.contains("(알 수 없음)")) {
        it.remove(); // 삭제
    }
}

it = list.iterator();
while (it.hasNext()) {
    System.out.println(it.next());
}
it = list.iterator();
while (it.hasNext()) {
    String s = it.next();
    if (s.contains("(알 수 없음)")) {
        it.remove(); // 삭제
    } else {
    System.out.println(it.next());
    }
}

위 코드를 아래 코드로 실행했을 때 오류가 발생하는데 이유를 알고 싶습니다 !

 

while (it.hasNext()) -> 리스트에서 다음 값을 불러 낼 수 있는 동안 반복하며

if(s.contains("(알 수 없음)")) { it.remove();} -> '("알 수 없음")' 을 포함한다면 제거하고

else {System.out.println(it.next());} ->그것이 아니라면 출력해라

 

로 생각해서 가능할 것 같은데 오류가 나서 궁금증이 생겼습니다 !

감사합니다 :)

답변 1

0

나도코딩님의 프로필 이미지
나도코딩
지식공유자

안녕하세요?

먼저 첫 번째 질문에 답변 드립니다.

작성해주신 두 코드는 같은 로직을 수행하며, 예제의 상황에서는 동작에 아무런 차이가 없습니다.
다만 String s 변수에 값을 담아두는 경우 아래와 같은 이점이 있을 수 있어요.

  1. 이후에 해당 객체를 여러 번 참조하거나 다른 로직에 활용하기 쉬워요.

  2. 코드를 확장하거나 디버깅할 때 수월할 수 있어요.

결론적으로 동작 자체에는 문제도 없고 차이도 없습니다. 단, 해당 값을 여러 곳에서 재사용할 필요가 있다거나, 현재 순회에서의 값은 무엇인지 디버깅 등을 통해 확인하고자 하는 경우에는 String s 변수로 두는 것이 유리할 수 있습니다. 이러한 필요에 따라 코드를 어떠한 스타일로 작성할지 결정하시면 됩니다 :)

 

두 번째 질문에 답변 드립니다.

먼저 코드 1과 코드 2의 동작은 다르게 작성되었습니다.

 

[코드 1]

it = list.iterator();
while (it.hasNext()) {
    String s = it.next(); // it.next() 를 한 번만 수행
    if (s.contains("(알 수 없음)")) {
        it.remove(); // 삭제
    }
}

it = list.iterator();
while (it.hasNext()) {
    System.out.println(it.next());
}

 

[코드 2]

it = list.iterator();
while (it.hasNext()) {
    String s = it.next(); // 1) it.next() 를 처음 실행
    if (s.contains("(알 수 없음)")) {
        it.remove(); // 삭제
    } else {
        System.out.println(it.next()); // 2) it.next() 를 한 번 더 실행
    }
}

코드 1에서는 하나의 반복 내에서 it.next() 를 한 번만 수행하는 반면에 코드 2에서는 it.next() 를 처음 실행하고 나서 else 구문을 만나게 되면 한 번 더 수행을 하게 됩니다. 다음 순회로 바로 건너 뛰어버리는 것이죠. 즉 하나의 반복에서 2개의 요소를 꺼내게 되는 경우가 발생하게 됩니다. 이는 의도와는 다른 동작이 되는 것인데요.

이를 방지하기 위해서는 첫 번째 질문에서 답변드린 것처럼 코드를 아래와 같이 수정하시면 됩니다. 출력하는 부분에 it.next() 대신 s 변수를 활용하는 것입니다.

it = list.iterator();
while (it.hasNext()) {
    String s = it.next();   // 1) it.next() 를 한 번만 실행
    if (s.contains("(알 수 없음)")) {
        it.remove();        // 2) 삭제
    } else {
        System.out.println(s); // 3) 삭제 대상이 아니라면 출력
    }
}

이렇게 수정 후 다시 한번 확인을 부탁드리며, 궁금증 해결에 도움되길 바라겠습니다 🙂

감사합니다.

김재훈님의 프로필 이미지
김재훈
질문자

답변 감사합니다 !

변수를 선언해두는 게 여러모로 도움이 되는군요 :)