item 42 leekyunghee - JAVA-JIKIMI/EFFECTIVE-JAVA3 GitHub Wiki

읡λͺ…(μ΄λ¦„μ—†λŠ”) 클래슀 λ³΄λ‹€λŠ” λžŒλ‹€λ₯Ό μ‚¬μš©ν•˜λΌ

  • μžλ°”μ—μ„œ ν•¨μˆ˜ νƒ€μž…μ„ ν‘œν˜„ν•  λ•Œ 좔상 λ©”μ„œλ“œλ₯Ό ν•˜λ‚˜λ§Œ 담은 μΈν„°νŽ˜μ΄μŠ€(λ“œλ¬Όκ²ŒλŠ” 좔상 클래슀)λ₯Ό μ‚¬μš©ν–ˆλ‹€.
  • λžŒλ‹€λŠ” ν•¨μˆ˜λ‚˜ 읡λͺ… ν΄λž˜μŠ€μ™€ κ°œλ…μ€ λΉ„μŠ·ν•˜μ§€λ§Œ 훨씬 κ°„κ²°ν•˜λ‹€.
  • 이런 μΈν„°νŽ˜μ΄μŠ€μ˜ μΈμŠ€ν„΄μŠ€λ₯Ό ν•¨μˆ˜ 객체라고 ν•˜μ—¬ νŠΉμ • ν•¨μˆ˜λ‚˜ λ™μž‘μ„ λ‚˜νƒ€λ‚΄λŠ” 데 썼닀.

λ¬Έμžμ—΄μ„ 길이순으둜 μ •λ ¬ν•˜λŠ”λ° 정렬을 μœ„ν•œ 비ꡐ ν•¨μˆ˜λ‘œ 읡λͺ… 클래슀λ₯Ό μ‚¬μš©ν•œλ‹€.

import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import static java.util.Comparator.*;

import static java.util.Comparator.comparingInt;

// ν•¨μˆ˜ 객체둜 μ •λ ¬ν•˜κΈ° (254-255μͺ½)
public class SortFourWays {
    public static void main(String[] args) {
        List<String> words = Arrays.asList(args);

        // μ½”λ“œ 42-1 읡λͺ… 클래슀의 μΈμŠ€ν„΄μŠ€λ₯Ό ν•¨μˆ˜ 객체둜 μ‚¬μš© - 낑은 기법이닀! (254μͺ½)
        // Comparator μΈν„°νŽ˜μ΄μŠ€κ°€ 정렬을 λ‹΄λ‹Ήν•˜λŠ” 좔상 μ „λž΅μ„ λœ»ν•˜λ©° λ¬Έμžμ—΄μ„ μ •λ ¬ν•˜λŠ” ꡬ체적인 μ „λž΅μ„ 읡λͺ… 클래슀둜 κ΅¬ν˜„ 
        Collections.sort(words, new Comparator<String>() {
            public int compare(String s1, String s2) {
                return Integer.compare(s1.length(), s2.length());
            }
        });
        System.out.println(words);
        Collections.shuffle(words);

        // μ½”λ“œ 42-2 λžŒλ‹€μ‹μ„ ν•¨μˆ˜ 객체둜 μ‚¬μš© - 읡λͺ… 클래슀 λŒ€μ²΄
        Collections.sort(words,
                (s1, s2) -> Integer.compare(s1.length(), s2.length()));
        System.out.println(words);
        Collections.shuffle(words);

        // λžŒλ‹€ μžλ¦¬μ— λΉ„κ΅μž 생성 λ©”μ„œλ“œ(λ©”μ„œλ“œ 참쑰와 ν•¨κ»˜)λ₯Ό μ‚¬μš©
        Collections.sort(words, comparingInt(String::length));
        System.out.println(words);
        Collections.shuffle(words);

        // λΉ„κ΅μž 생성 λ©”μ„œλ“œμ™€ ListμΈν„°νŽ˜μ΄μŠ€μ— μΆ”κ°€λœ sort λ©”μ„œλ“œλ₯Ό μ‚¬μš© 
        words.sort(comparingInt(String::length));
        System.out.println(words);
    }
}
  • 읡λͺ… 클래슀 방식은 μ½”λ“œκ°€ λ„ˆλ¬΄ κΈΈκΈ° λ•Œλ¬Έμ— ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ°μ— μ ν•©ν•˜μ§€ μ•ŠμŒ
  • μžλ°” 8μ—μ™€μ„œ 좔상 λ©”μ„œλ“œ ν•˜λ‚˜μ§œλ¦¬ μΈν„°νŽ˜μ΄μŠ€λŠ” νŠΉλ³„ν•œ 의미λ₯Ό 인정 λ°›μŒ
  • λžŒλ‹€λŠ” ν•¨μˆ˜λ‚˜ 읡λͺ… ν΄λž˜μŠ€μ™€ κ°œλ…μ€ λΉ„μŠ·ν•˜μ§€λ§Œ μ½”λ“œλŠ” 훨씬 κ°„κ²°

νƒ€μž…μ„ λͺ…μ‹œν•΄μ•Ό μ½”λ“œκ°€ 더 λͺ…ν™•ν•  λ•Œλ§Œ μ œμ™Έν•˜κ³ λŠ” λžŒλ‹€μ˜ λͺ¨λ“  λ§€κ°œλ³€μˆ˜ νƒ€μž…μ€ μƒλž΅ν•˜μž.

  • νƒ€μž… μΆ”λ‘  κ·œμΉ™
  • 상황에 따라 μ»΄νŒŒμΌλŸ¬κ°€ νƒ€μž…μ„ κ²°μ •ν•˜μ§€ λͺ»ν•  μˆ˜λ„ μžˆλŠ”λ° 그럴 λ•ŒλŠ” ν”„λ‘œκ·Έλž˜λ¨Έκ°€ 직접 λͺ…μ‹œν•΄μ•Ό ν•œλ‹€.

λžŒλ‹€λ₯Ό μ΄μš©ν•˜λ©΄ μ—΄κ±° νƒ€μž…μ˜ μΈμŠ€ν„΄μŠ€ ν•„λ“œλ₯Ό μ΄μš©ν•˜λŠ” λ°©μ‹μœΌλ‘œ μƒμˆ˜λ³„λ‘œ λ‹€λ₯΄κ²Œ λ™μž‘ν•˜λŠ” μ½”λ“œλ₯Ό μ‰½κ²Œ κ΅¬ν˜„ν•  수 μžˆλ‹€

  1. λ‹¨μˆœνžˆ 각 μ—΄κ±° νƒ€μž… μƒμˆ˜μ˜ λ™μž‘μ„ λžŒλ‹€λ‘œ κ΅¬ν˜„ν•΄ μƒμ„±μžμ— λ„˜κΈ°κ³  μƒμ„±μžλŠ” 이 λžŒλ‹€λ₯Ό μΈμŠ€ν„΄μŠ€ ν•„λ“œλ‘œ μ €μž₯ν•΄ λ‘”λ‹€.
  2. apply λ©”μ„œλ“œμ—μ„œ ν•„λ“œμ— μ €μž₯된 λžŒλ‹€λ₯Ό ν˜ΈμΆœν•˜κΈ°λ§Œ ν•˜λ©΄ λœλ‹€.

μ—΄κ±° νƒ€μž… μƒμˆ˜μ˜ λ™μž‘μ„ ν‘œν˜„ν•œ λžŒλ‹€λ₯Ό DoubleBinaryOperator μΈν„°νŽ˜μ΄μŠ€ λ³€μˆ˜μ— ν• λ‹Ήν–ˆλ‹€. Double νƒ€μž… 인수 2개λ₯Ό λ°›μ•„ Double νƒ€μž… κ²°κ³Όλ₯Ό λŒλ €μ€€λ‹€.

import java.util.function.DoubleBinaryOperator;

// μ½”λ“œ 42-4 ν•¨μˆ˜ 객체(λžŒλ‹€)λ₯Ό μΈμŠ€ν„΄μŠ€ ν•„λ“œμ— μ €μž₯ν•΄ μƒμˆ˜λ³„ λ™μž‘μ„ κ΅¬ν˜„ν•œ μ—΄κ±° νƒ€μž…
public enum Operation {
    PLUS  ("+", (x, y) -> x + y),
    MINUS ("-", (x, y) -> x - y),
    TIMES ("*", (x, y) -> x * y),
    DIVIDE("/", (x, y) -> x / y);

    private final String symbol;
    private final DoubleBinaryOperator op;

    Operation(String symbol, DoubleBinaryOperator op) {
        this.symbol = symbol;
        this.op = op;
    }

    @Override public String toString() { return symbol; }

    public double apply(double x, double y) {
        return op.applyAsDouble(x, y);
    }

    // μ•„μ΄ν…œ 34의 메인 λ©”μ„œλ“œ (215μͺ½)
    public static void main(String[] args) {
        double x = Double.parseDouble(args[0]);
        double y = Double.parseDouble(args[1]);
        for (Operation op : Operation.values())
            System.out.printf("%f %s %f = %f%n",
                    x, op, y, op.apply(x, y));
    }
}

λžŒλ‹€λ₯Ό μ“Έ 수 μ—†λŠ” 경우

  • 좔상 클래슀의 μΈμŠ€ν„΄μŠ€λ₯Ό λ§Œλ“€ λ•Œ λžŒλ‹€λ₯Ό μ“Έ 수 μ—†μœΌλ‹ˆ 읡λͺ… 클래슀λ₯Ό μ¨μ•Όν•œλ‹€.
  • 좔상 λ©”μ„œλ“œκ°€ μ—¬λŸ¬κ°œμΈ μΈν„°νŽ˜μ΄μŠ€μ˜ μΈμŠ€ν„΄μŠ€λ₯Ό λ§Œλ“€ λ•Œλ„ 읡λͺ… 클래슀λ₯Ό μ“Έ 수 μžˆλ‹€.

λžŒλ‹€λŠ” μžμ‹ μ„ μ°Έμ‘°ν•  수 μ—†λ‹€. λžŒλ‹€μ—μ„œμ˜ this ν‚€μ›Œλ“œλŠ” λ°”κΉ₯ μΈμŠ€ν„΄μŠ€λ₯Ό 가리킨닀.

읡λͺ… ν΄λž˜μŠ€μ—μ„œ this λŠ” 자기 μžμ‹ μ΄λ―€λ‘œ ν•¨μˆ˜ 객체가 μžμ‹ μ„ μ°Έμ‘°ν•΄μ•Ό ν•œλ‹€λ©΄ 읡λͺ… 클래슀λ₯Ό μ¨μ•Όν•œλ‹€.

핡심 정리

λžŒλ‹€λ₯Ό 직렬화(읡λͺ… 클래슀의 μΈμŠ€ν„΄μŠ€λ„ λ§ˆμ°¬κ°€μ§€) ν•˜λŠ” 일은 극히 μ‚Όκ°€μ•Ό ν•œλ‹€. 
읡λͺ… ν΄λž˜μŠ€λŠ” (ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€κ°€ μ•„λ‹Œ) νƒ€μž…μ˜ μΈμŠ€ν„΄μŠ€λ₯Ό λ§Œλ“€ λ•Œλ§Œ μ‚¬μš©ν•˜λΌ. 
직렬화 ν•΄μ•Όν•˜λŠ” ν•¨μˆ˜ 객체가 μžˆλ‹€λ©΄ Comparator처럼 private 정적 쀑첩 클래슀의 μΈμŠ€ν„΄μŠ€λ₯Ό μ‚¬μš©ν•˜μž.
⚠️ **GitHub.com Fallback** ⚠️