문제

객체의 반복자를 사용할 때 while 루프 (Java를 배우는 모든 책에 쓰여 있듯이, 자바로 생각하기 브루스 에켈의 글):

Iterator it=...

while(it.hasNext()){
    //...
}

하지만 언젠가 누군가가 대신에 for 루프:

Iterator it=...
for (Iterator it=...; it.hasNext();){
    //...
}

나는 이 선택을 이해하지 못합니다:

  • 나는 for 루프 순서 순서(배열) 또는 단계에 대한 특수 규칙(일반적으로 단순 증분으로 선언됨)이 있는 컬렉션이 있는 경우 counter++).
  • 나는 while 루프 루프가 끝나면 이 제약 조건은 없지만 종료를 위한 논리 조건만 있습니다.

다른 원인이 없는 스타일 코딩의 문제인가요, 아니면 제가 모르는 다른 로직(예: 성능)이 존재하는 건가요?

모든 피드백에 감사드립니다

도움이 되었습니까?

해결책

for 루프의 올바른 구문은 다음과 같습니다.

for (Iterator it = ...; it.hasNext(); ){
    //...
}

(코드의 이전 선언은 불필요하고 For Loop Heading의 추가 세미콜론입니다.)

이 구문을 사용하든 while 루프는 맛의 문제이며, 둘 다 정확히 동일하게 번역됩니다. For 루프의 일반적인 구문은 다음과 같습니다.

for (<init stmt>; <loop cond>; <iterate stmt>) { <body>; }

다음과 같습니다.

<init stmt>;
while (<loop cond>) { <body>; <iterate stmt>; }

편집하다: 실제로 위의 두 형태는 완전히 동등하지는 않습니다. 만약에 (질문에서와 같이) 변수는 init 문으로 선언됩니다. 이 경우 반복자 변수의 범위에 차이가 있습니다. FER 루프를 사용하면 스코프는 루프 자체로 제한되며, while 루프의 경우 스코프는 둘러싸는 블록의 끝까지 확장됩니다 (선언이 루프 외부에 있기 때문에 큰 놀라움은 없습니다).

또한 다른 사람들이 지적했듯이 새로운 버전의 Java에서는 For Loop에 대한 속기 표기법이 있습니다.

for (Iterator<Foo> it = myIterable.iterator(); it.hasNext(); ) {
    Foo foo = it.next();
    //...
}

다음과 같이 쓸 수 있습니다.

for (Foo foo : myIterable) {
    //...
}

이 양식을 사용하면 물론 반복하는 동안 컬렉션에서 항목을 삭제하려는 경우 반복자에 대한 직접 참조를 잃어 버립니다.

다른 팁

그것은 단지 스타일 일이며 당신처럼 나는 색인으로 무언가를 사용할 때 for 루프를 선호합니다. Java 5를 사용하는 경우 물론 어쨌든 컬렉션을 통해 Foreach 루프를 사용해야합니다.

Collection<String> someCollection = someCollectionOfString();
for (String element : someCollection) {
....
}

선언하는 목적 Iterator for 루프 내에서 변수의 범위를 최소화하십시오, 그것은 좋은 관행입니다.

당신이 선언 할 때 Iterator 루프 외에는 루프가 완료된 후에도 참조가 여전히 유효합니다. 시간의 99.99%, 당신은 계속 사용할 필요가 없습니다. Iterator 루프가 완료되면 이러한 스타일은 다음과 같은 버그로 이어질 수 있습니다.

//iterate over first collection
Iterator it1 = collection1.iterator();
while(it1.hasNext()) {
   //blah blah
}

//iterate over second collection
Iterator it2 = collection2.iterator();
while(it1.hasNext()) {
   //oops copy and paste error! it1 has no more elements at this point
}

첫 번째 방법 외에는이 두 가지 방법 사이에 큰 차이가 없습니다. it 루프 후. 두 번째 접근법은 루프 내부의 변수를 다시 고정하기 때문에 오류가 발생할 수 있습니다.

실제로 이것에는 세 번째 방법이 있습니다. 예를 들어 글을 쓰는 대신

for (Iterator<SomeObject> it = foo.iterator(); it.hasNext();) {
  SomeObject so = foo.next();
}

당신은 가장 자주 쓸 수 있습니다

for (SomeObject so: foo) {...}

이 두 사람은 같은 것과 동일합니다 ...

사람들은 단순히 그것이 더 깔끔하다고 느끼기 때문에 명시적인('이전 스타일') for 루프를 사용할 수 있습니다. 아마도 아직 새로운 구문에 적응하지 않았을 수도 있습니다(개인적으로 훨씬 더 깔끔하다고 생각합니다).

더 긴 for 루프 구성의 실제적인 장점 중 하나는 반복자에 대한 참조가 있으므로 반복자에 대해 메서드를 호출할 수 있다는 것입니다. next().특히, hasNext() 종종 호출하는 것이 유용할 수 있습니다. 쉼표로 구분된 문자열 목록을 인쇄하고 싶다면 다음과 같이 상상해 보세요.

StringBuilder sb = new StringBuilder();
for (Iterator it=...; it.hasNext();){
   sb.append(it.next());
   if (it.hasNext())
      sb.append(", ");
}

더 장황한 for 루프를 사용하는 경우 이와 같이 "이것이 마지막 것"인 경우를 구별하기 위한 것입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top