개발 기록

[이펙티브 자바] 아이템 58,59 본문

JAVA

[이펙티브 자바] 아이템 58,59

수염차 2025. 5. 27. 21:07

## 전통적인 for 문보다는 for-each 문을 사용하라

 

- 전통적인 for문

// 컬렉션 순회
for (Iterator<Element> i = c.iterator(); i.hasNext(); ){
	Element e = i.next();
    ...  //e로 무언가를 한다.
}
// 배열 순회
for (int i = 0; i < a.length; i++) {
    ..// a[i]로 무언가를 한다.
}

- 문제점 : 

  1. 반복자와 인덱스 변수는 코드만 지저분하게 할 뿐 꼭 필요한 것은 원소들뿐이다.
  2. 반복자와 인덱스 '변수'를 잘못 사용할 가능성이 높아진다.
  3. 컬렉션이나 배열이냐에 따라 코드 형태가 달라진다.

### for-each ( 향상된 for문(enhanced for statement) )

for (Element a : elements) {
	..// a로 무언가를 한다.
}

- 장점 :

 1. 반복자와 인덱스 변수를 사용하지 않으니 코드가 깔끔해지고 오류가 날 일도 없다

2. 하나의 관용구로 컬렉션과 배열을 모두 처리할 수 있어서 어떤 컨테이너를 다루는지는 신경 쓰지 않아도 된다.

3. 반복 대상이 컬렉션이든 배열이든, foreach문을 사용해도 속도는 그대로다.

4. 서로 크기가 다른 컬렉션 두개를 중첩으로 순회할 때 발생할 수 있는 실수 예방 가능

enum Suit { CLUB, DIAMOND, HEART, SPADE }
    enum Rank { ACE, DEUCE, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT,
        NINE, TEN, JACK, QUEEN, KING }

    static Collection<Suit> suits = Arrays.asList(Suit.values());
    static Collection<Rank> ranks = Arrays.asList(Rank.values());
    
    for (Iterator<Suit> i = suits.iterator(); i.hasNext(); )
          for (Iterator<Rank> j = ranks.iterator(); j.hasNext(); )
              deck.add(new Card(i.next(), j.next()));  // 문제 발생
              
              
    for (Suit suit : suits)
		for (Rank rank : ranks)
    		deck.add(new Card(suit, rank));

 

### For-each 문을 사용할 수 없는 경우

1. 파괴적인 필터링

컬렉션을 순회하면서 선택된 원소를 제거해야 하는 경우, for-each 대신 반복자의 remove 메서드를 호출해야 한다. 자바 8부터는 반복자를 사용하지 않고 컬렉션 단에서 removeIf 를 통해 제거할 수 있다.

2. 변형

순회하면서 특정 원소의 값 혹은 전체를 교체해야 한다면 리스트의 반복자나 배열의 인덱스를 사용해야 한다.

3. 병렬 반복

여러 컬렉션을 병렬로 순회해야 한다면 각각의 반복자와 인덱스 변수를 사용해 엄격하고 명시적으로 제어해야 한다.

 

### 핵심 정리
전통적인 for문과 비교했을 때 for-each문은 명료하고, 유연하고, 버그를 예방해준다. 성능 저하도 없으므로 가능한 모든 곳에서 for 문이 아닌 for-each 문을 사용하자.

 


 

## 라이브러리를 익히고 사용하라

 

### 표준 라이브러리를 쓰는 것의 이점

  • 전문가의 지식과 경험을 활용할 수 있다.
  • 핵심 비즈니스로직 외에 다른 것을 작성하는데 낭비하는 시간을 줄인다.
  • 따로 노력하지 않아도 성능이 지속해서 개선된다.
  • 패치를 거듭할수록 기능이 점점 많아진다.
  • 많은 사람들에게 낯익은 코드가 되어 협업하기 좋다.
  • 메이저 릴리즈에 주목할만한 수많은 기능이 라이브러리에 추가된다.

### 자바9 에서 추가된 transferTo()의 예

@Test
public void urlTest() throws IOException {
    try (InputStream in = new URL("https://dbpia.co.kr").openStream()) {
        in.transferTo(System.out);
    }
}
  • 기존에 까다로운 코드로 구현해야 했던, URL 내용 가져오는 부분을 쉽게 구현할 수 있다.

### 핵심정리

일반적으로 라이브러리의 코드는 여러분이 직접 작성한 것보다 품질이 좋고, 점차 개선될 가능성이 크다.

코드품질에도 규모의 경제가 적용된다.

즉, 라이브러리 코드는 개발자 각자가 작성하는 것보다 주목을 훨씬 많이 받으므로 코드 품질도 그만큼 높아진다.

'JAVA' 카테고리의 다른 글

[이펙티브 자바] 아이템 59,60  (0) 2025.05.27
[이펙티브 자바] 아이템 47  (0) 2025.05.06
[이펙티브 자바] 아이템 57  (0) 2025.05.06
[이펙티브 자바] 아이템 48  (0) 2025.05.06
[이펙티브 자바] 아이템 44  (0) 2025.04.08
Comments