JavaBookStudy / JavaBook

책읽기 스터디
https://javabookstudy.github.io/
Apache License 2.0
19 stars 2 forks source link

[Effective Java] Item 58. 병렬 순회와 for-each를 사용해서는 안되는 이유? #34

Closed taxol1203 closed 3 years ago

taxol1203 commented 3 years ago

for-each를 사용할 수 없는 예 중에서 병렬 반복을 할 수 없다고 합니다.
그리고 병렬 반복으로 인하여 문제가 생긴 경우가 코드 58-4라고 간단히 설명되어있는데,
이 코드는 다음과 같은 for-each로 해결하였습니다.

for (Suit suit : suits) {
  for (Rank rank : ranks) {
    deck.add(new Card(suit, rank));
  }
}

물론 위 코드는 중첩 순회인 경우지만, 병렬 반복과 왜 for-each를 사용할 수 없는지 궁금합니다!

daebalprime commented 3 years ago

수업에서 다뤘던 SWEA 하나로 문제의 경우 INPUT이 아래와 같이 주어집니다. 10 // 테케갯수 2 // 맵 크기 0 0 // 각 섬의 x좌표 0 100 // 각 섬의 y좌표 ...

일반적으로 섬의 좌표를 담는 배열이나 컬렉션을 만들고 순회를 2번 하겠지만, 최적화에 눈돌아가서 한 번의 순회에 마칠 수 없을까 고민하다가 입력을 다음과 같이 받았습니다.

StringTokenizer st = new StringTokenizer(br.readLine()); StringTokenizer st2 = new StringTokenizer(br.readLine()); for(int i = 0; i < N; i++) {
int x = Integer.parseInt(st.nextToken()); int y = Integer.parseInt(st2.nextToken()); islands[i] = new Island(x,y); }

토크나이저 2개를 선언하여 한 번의 순회에 섬 정보를 모두 해결하는 코드입니다. 해당 코드를 for-each문으로 작성할 수 없는건 자명하지 않나 생각합니다.

kjsu0209 commented 3 years ago

코드 58-4는 suits와 rank를 한 번에 같이 돌리고자 했지만, 하나의 반복자가 suits와 rank의 원소를 다 담을 수는 없기 때문에 이중 for문으로 만들었습니다.

이중 for문으로 돌리면 두 컬렉션이 병렬로, 같은 횟수로 반복하는 게 아니게 되죠. @daebalprime 님의 답변처럼 하나의 for문 안에서 변수 두 개를 사용하여 반복하는 것이 더 안전합니다.

따라서 foreach에서 병렬 반복이 불가능한 이유는 하나의 반복자가 여러 컬렉션을 담을 수 없기 때문이라고 보면 됩니다.