CHAP02 - Modern-Java-in-Action/Online-Study GitHub Wiki

λ™μž‘ νŒŒλΌλ―Έν„°ν™” μ½”λ“œ μ „λ‹¬ν•˜κΈ°

λ™μž‘μ„ νŒŒλΌλ―Έν„°ν™”ν•˜λ©΄ ν•¨μˆ˜λ₯Ό λ‹€λ₯Έ λ©”μ„œλ“œμ˜ 맀개인자둜 λ„˜κΈΈ 수 μžˆλ‹€. 쒋은 μ˜ˆλŠ” Collections.sort()λ©”μ„œλ“œμ— Comparator 읡λͺ…ν΄λž˜μŠ€λ‘œ 감싼 compare() λ₯Ό μ „λ‹¬ν•˜λŠ” κ²½μš°μ΄λ‹€.

2μž₯μ—μ„œλŠ” μ΄λŸ¬ν•œ λ™μž‘ νŒŒλΌλ―Έν„°ν™”κ°€ μ™œ ν•„μš”ν•œμ§€λ₯Ό μ„€λͺ…ν•œλ‹€. μžλ°”8 μ΄ν›„λ‘œ λ™μž‘ νŒŒλΌλ―Έν„°ν™”λ₯Ό μ–΄λ–»κ²Œ ν•˜λŠ”μ§€, 이λ₯Όν…Œλ©΄ λžŒλ‹€ν‘œν˜„μ‹κ³Ό λ©”μ„œλ“œ μ§μ ‘μ°Έμ‘°λŠ” 3μž₯μ—μ„œ ꡬ체적으둜 닀룬닀.

λ©”μ„œλ“œ : ν΄λž˜μŠ€μ— μ’…μ†λœ λ™μž‘
ν•¨μˆ˜ : ν΄λž˜μŠ€μ— μ’…μ†λ˜μ§€ μ•Šμ€ λ™μž‘

1. λ™μž‘ νŒŒλΌλ―Έν„°ν™”κ°€ μ™œ ν•„μš”ν• κΉŒ

μ»¬λ ‰μ…˜μ— λ‹€μŒκ³Ό 같은 λ©”μ„œλ“œλ₯Ό κ΅¬ν˜„ν•œλ‹€κ³  κ°€μ •ν•΄λ³΄μž. 이 λ©”μ„œλ“œκ°€ μ–΄λ–€ λ™μž‘μ„ μˆ˜ν–‰ν• μ§€ μ •ν•΄μ§€μ§€ μ•Šμ€ μƒνƒœμ΄λ‹€. 상황에 따라 λ‹€μ–‘ν•œ λ™μž‘μ„ μˆ˜ν–‰ν•˜κ³ , μ‹œμ‹œλ•Œλ•Œλ‘œ λ³€ν™”ν•˜λŠ” μš”κ΅¬μ‚¬ν•­μ„ λ§žμΆ”λ €λ©΄ λ³΅μž‘ν•œ μ½”λ“œλ₯Ό μž‘μ„±ν•΄μ•Ό ν•˜κ² λ‹€.

  • 리슀트의 λͺ¨λ“  μš”μ†Œμ— λŒ€ν•΄ 'μ–΄λ–€ λ™μž‘'을 μˆ˜ν–‰ν•  수 있음
  • 리슀트의 κ΄€λ ¨ μž‘μ—…μ„ 끝낸 λ‹€μŒ 'μ–΄λ–€ λ‹€λ₯Έ λ™μž‘'을 μˆ˜ν–‰ν•  수 있음
  • μ—λŸ¬κ°€ λ°œμƒν•˜λ©΄ 'μ •ν•΄μ§„ μ–΄λ–€ λ‹€λ₯Έ λ™μž‘'을 μˆ˜ν–‰ν•  수 있음

κ·Έ λŒ€μ‹ μ— μ–΄λ–€ λ™μž‘μ„ μˆ˜ν–‰ν• μ§€ λ©”μ†Œλ“œμ˜ 맀개인자둜 λ„˜κ²¨λ°›μœΌλ©΄ μ–΄λ–¨κΉŒ?

2. λ™μž‘μ„ νŒŒλΌλ―Έν„°ν™”ν•˜λŠ” 방법듀

κΈ°λ³Έ μ˜ˆμ œμ½”λ“œλŠ” λ‹€μŒκ³Ό κ°™λ‹€.

enum Color {RED, GREEN}

public class Apple {
    Color color;
    Integer weight;

    Apple(Color color, int weight, int no){
        this.color = color;
        this.weight = Integer.valueOf(weight);
        this.no = Integer.valueOf(no);
    }

    public Color getColor(){return this.color;}
    public Integer getWeight(){return this.weight;}
}
List<Apple> inventory = new ArrayList<>();
inventory.add(new Apple(Color.GREEN, 500));
inventory.add(new Apple(Color.RED, 750));
inventory.add(new Apple(Color.RED, 400));
inventory.add(new Apple(Color.GREEN, 600));
inventory.add(new Apple(Color.RED, 100));
inventory.add(new Apple(Color.GREEN, 2000));

2.1. ν”„λ¦¬λ””μΌ€μ΄νŠΈ

무게 λ˜λŠ” 색을 κ΅¬λΆ„ν•˜κΈ° μœ„ν•΄ if-else문을 각각 μž‘μ„±ν•˜λŠ” λŒ€μ‹ μ— ν•΄λ‹Ή λ™μž‘μ„ ν”„λ¦¬λ””μΌ€μ΄νŠΈ ν•¨μˆ˜μ— λ‹΄μ•„ 전달받을 수 μžˆλ‹€.

ν”„λ¦¬λ””μΌ€μ΄νŠΈλŠ” μ°Έ λ˜λŠ” 거짓을 λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜μ΄λ‹€. 단 ν•˜λ‚˜μ˜ ν•¨μˆ˜λ§Œ κ°€μ§€λŠ” ν”„λ¦¬λ””μΌ€μ΄νŠΈ μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ •μ˜ν•˜κ³ , ν•΄λ‹Ή ν”„λ¦¬λ””μΌ€μ΄νŠΈλ₯Ό 상황에 맞게 κ΅¬ν˜„ν•˜μ—¬ μ‚¬μš©ν•œλ‹€.

μΈν„°νŽ˜μ΄μŠ€ μ •μ˜

μ•„λž˜μ™€ 같이 직접 μ •μ˜ν•΄μ„œ μ‚¬μš©ν•  수 μžˆλ‹€.

public interface ApplePredicate{
	boolean test(Apple apple);
}

λ˜λŠ” java.util.function μ•„λž˜ Predicate<T> μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•΄ μ‚¬μš©ν•΄λ„ λœλ‹€. boolean으둜 μ°Έ/거짓을 λ°˜ν™˜ν•˜λŠ” test() ν•¨μˆ˜, ν”„λ¦¬λ””μΌ€μ΄νŠΈκ°„ AND/OR/NOT 연산을 μˆ˜ν–‰ν•˜λŠ” ν•¨μˆ˜ 등이 μ •μ˜λ˜μ–΄ μžˆλ‹€.

μΈν„°νŽ˜μ΄μŠ€ κ΅¬ν˜„

ν”„λ¦¬λ””μΌ€μ΄νŠΈ μΈν„°νŽ˜μ΄μŠ€λŠ” μ•„λž˜μ™€ 같이 κ΅¬ν˜„ν•΄μ„œ μ‚¬μš©ν•œλ‹€.

public class AppleHeavyWeightPredicate implements ApplePredicate{
	public boolean test(Apple apple){
        return apple.getWeight() > 150;
    }
}
public class AppleGreenColorPredicate implements ApplePredicate{
    public boolean test(Apple apple){
        return GREEN.equals(apple.getColor());
    }
}

λ©”μ„œλ“œλ‘œ μ „λ‹¬ν•˜κΈ°

if-else λŒ€μ‹  쑰건식을 ν”„λ¦¬λ””μΌ€μ΄νŠΈ ν•¨μˆ˜λ‘œ 전달받아 μˆ˜ν–‰ν•˜λŠ” μ½”λ“œμ΄λ‹€. 보닀 μœ μ—°ν•˜κ²Œ λ™μž‘ν•˜λŠ”λ°λ‹€ 가독성도 μ’‹λ‹€.

public static List<Apple> filterApples(List<Apple> inventory, ApplePredicate p){
	List<Apple> result = new ArrayList<>();
    for(Apple apple : inventory){
        if(p.test(apple)){
            result.add(apple);
        }
    }
    return result;
}

λ‹€λ§Œ, λ©”μ„œλ“œλ₯Ό 클래슀둜 감싸 μ „λ‹¬ν•˜λ―€λ‘œ μ½”λ“œκ°€ λΆˆν•„μš”ν•˜κ²Œ μ€‘λ³΅λœλ‹€.

λ‹€μ–‘ν•œ ν™œμš©λ°©λ²•

voidλ₯Ό λ°˜ν™˜ν•˜κ±°λ‚˜ String을 λ°˜ν™˜ν•˜λŠ” ν”„λ¦¬λ””μΌ€μ΄νŠΈλ₯Ό κ΅¬ν˜„ν•  μˆ˜λ„ μžˆλ‹€. 이λ₯Όν…Œλ©΄ μ»¬λ ‰μ…˜ 객체λ₯Ό 검사해 좜λ ₯ν•  λ©”μ‹œμ§€λ₯Ό λ‹€λ₯΄κ²Œ μ„€μ •ν•  수 μžˆκ² λ‹€.

public interface AppleFormatter{
	String accept(Apple a);
}

Java의 Predicate<T>λŠ” booleanλ§Œμ„ λ°˜ν™˜ν•˜λ―€λ‘œ, λ‹€μ–‘ν•œ ν™œμš©μ„ μœ„ν•΄μ„œλŠ” 직접 μ •μ˜ν•΄μ„œ μ‚¬μš©ν•΄μ•Ό ν•˜κ² λ‹€. λ‹€λ§Œ, μΈν„°νŽ˜μ΄μŠ€μ— 두 개 이상 ν•¨μˆ˜λ₯Ό μ •μ˜ν•˜λ©΄ @functionalInterface μ–΄λ…Έν…Œμ΄μ…˜μ„ λ‹¬μ•˜μ„ λ•Œ μ—λŸ¬κ°€ λœ¬λ‹€. ν”„λ¦¬λ””μΌ€μ΄νŠΈ μΈν„°νŽ˜μ΄μŠ€λŠ” 단 ν•˜λ‚˜μ˜ ν•¨μˆ˜λ§Œμ„ κ°€μ Έμ•Ό ν•œλ‹€.

2.2. 읡λͺ… 클래슀

2.1.의 AppleHeavyWeightPredicate와 AppleGreenColorPredicateλŠ” ν•¨μˆ˜λ₯Ό μ „λ‹¬ν•˜κΈ°λ§Œ ν•œλ‹€. μ•„λž˜μ™€ 같이 읡λͺ… 클래슀둜 ν”„λ¦¬λ””μΌ€μ΄νŠΈλ₯Ό μž‘μ„±ν•΄ μ „λ‹¬ν•˜λ©΄ 보닀 κ°„κ²°ν•˜κ²Œ ν‘œν˜„ν•  수 μžˆλ‹€.

List<Apple> redApples = filterApples(inventory, new ApplePredicate(){
    public boolean test(Apple a){
        return RED.equals(a.getColor());
    }
});

κ·ΈλŸ¬λ‚˜ λ‹€μŒκ³Ό 같이 객체 μŠ€μ½”ν”„κ°€ λ³΅μž‘ν•΄μ§€λŠ” λ¬Έμ œκ°€ μžˆλ‹€. λ‹€μŒ μ½”λ“œμ˜ 결과값은 λ¬΄μ—‡μΌκΉŒ?

public class MeaningOfThis{
	public final int value = 4;
	public void doIt(){
		int value = 6;
        Runnable r = new Runnable(){
            public final int value = 5;
            public void run(){
                int value = 10;
                System.out.println(this.value);
            }
        };
        r.run();
	}
    
    public static void main(String...args){
     	MeaningOfThis m = new MeaningOfThis();
        m.doIt();
    }
}
μ •λ‹΅ 5

this ν‚€μ›Œλ“œ

μΈμŠ€ν„΄μŠ€ λ©”μ„œλ“œ λ˜λŠ” μƒμ„±μž μ•ˆμ—μ„œ this ν‚€μ›Œλ“œλ‘œ ν˜„μž¬ 객체λ₯Ό μ°Έμ‘°ν•  수 μžˆλ‹€. μ§€μ—­ 멀버 λ˜λŠ” λ§€κ°œλ³€μˆ˜λ‘œ μƒμœ„ 멀버가 κ°€λ €μ§€κΈ° λ•Œλ¬Έμ΄λ‹€. this ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•΄ ν˜„μž¬ 객체의 λͺ¨λ“  멀버λ₯Ό μ°Έμ‘°ν•  수 μžˆλ‹€.

λ˜ν•œ μ•„λž˜μ™€ 같이 μƒμ„±μž μ½”λ“œ 쀑볡을 ν”Όν•˜κΈ° μœ„ν•΄ μ‚¬μš©ν•  μˆ˜λ„ μžˆλ‹€. 이 경우 thisλŠ” μƒμ„±μžμ˜ 첫 번째 ν–‰μ—μ„œ ν˜ΈμΆœλ˜μ–΄μ•Ό ν•œλ‹€.

public class Coordinate{
	public int x;
    public int y;
    
    public Coordinate(int x){
        this(x, 0);
    }
    
    public Coordinate(int y){
        this(0, y);
    }
    
    public Coordinate(int x, int y){
        this.x = x;
        this.y = y;
    }
}

좜처 : Using the this Keyword (The Javaβ„’ Tutorials > Learning the Java Language > Classes and Objects) (oracle.com)

2.3. λžŒλ‹€ ν‘œν˜„μ‹

읡λͺ… 클래슀λ₯Ό μ•„λž˜μ™€ 같이 더 κ°„κ²°ν•˜κ²Œ ν‘œν˜„ν•  수 μžˆλ‹€.

List<Apple> result = filterApples(inventory, (Apple apple) -> RED.equals(apple.getColor()));

μ΄λŸ¬ν•œ ν‘œν˜„μ‹μ„ λžŒλ‹€λΌκ³  ν•œλ‹€. μ’…λ₯˜λŠ” μ•„λž˜μ™€ 같이 두 κ°€μ§€κ°€ μžˆλŠ”λ°, λžŒλ‹€λŠ” 인자, ν™”μ‚΄ν‘œ, λͺΈμ²΄λ‘œ κ΅¬μ„±λ˜μ–΄ μžˆλ‹€. ꡬ체적인 μ‚¬μš©λ²•μ€ 3μž₯μ—μ„œ 닀룬닀.

  • (인자) -> expression : κ΄„ν˜Έ μ•ˆ 인자λ₯Ό 전달받아 ν™”μ‚΄ν‘œ λ’€μ˜ ν‘œν˜„μ‹μ„ μˆ˜ν–‰ν•˜κ³  κ·Έ 결과값을 λ°˜ν™˜ν•œλ‹€λŠ” μ˜λ―Έμ΄λ‹€. ν‘œν˜„μ‹μ€System.out.printlnκ³Ό 같이 voidλ₯Ό λ°˜ν™˜ν•˜λŠ” κ²½μš°λ„ μžˆλ‹€.

  • (인자) -> { statements; } : κ΄„ν˜Έ μ•ˆ 인자λ₯Ό 전달받아 ν™”μ‚΄ν‘œ λ’€ μ€‘κ΄„ν˜Έ μ•ˆμ˜ λ¬Έμž₯을 μˆ˜ν–‰ν•œλ‹€λŠ” μ˜λ―Έμ΄λ‹€. λ°˜ν™˜κ°’μ΄ μžˆλ‹€λ©΄ return을 μ‚¬μš©ν•΄ λͺ…μ‹œμ μœΌλ‘œ ν‘œμ‹œν•΄μ£Όμ–΄μ•Ό ν•œλ‹€.

ν‘œν˜„μ‹(expression): 식을 μ²˜λ¦¬ν•˜λ©΄ 'ν•˜λ‚˜μ˜ κ°’'을 λ°˜ν™˜. 이λ₯Όν…Œλ©΄ int variable = 0κ³Ό 같은 할당식은 μ„±κ³΅μ‹œ intλ₯Ό λ°˜ν™˜ν•˜λŠ” ν‘œν˜„μ‹μ΄λ©°, System.out.println(variable)은 Voidλ₯Ό λ°˜ν™˜ν•˜λŠ” ν‘œν˜„μ‹μ΄λ‹€.

λ¬Έμž₯(statements): 할당식, λ³€μˆ˜ 증감(++ --), λ©”μ„œλ“œ 호좜, 객체 생성, μ œμ–΄λ¬Έ λ“± μˆ˜ν–‰ν•  μž‘μ—…μ˜ ν•œ λ‹¨μœ„μ΄λ‹€. 일뢀 λ¬Έμž₯은 ; 없이 ν‘œν˜„μ‹μœΌλ‘œ μ‚¬μš©ν•  μˆ˜λ„ μžˆλ‹€.

좜처 : Expressions, Statements, and Blocks (The Javaβ„’ Tutorials > Learning the Java Language > Language Basics) (oracle.com)

2.4. μ œλ„€λ¦­μœΌλ‘œ 리슀트 μ›μ†Œ ν˜•μ‹μ„ 좔상화

μ œλ„€λ¦­μ„ μ‚¬μš©ν•΄ 리슀트 μ›μ†Œ ν˜•μ‹μ„ μΆ”μƒν™”ν•œ κ²½μš°μ΄λ‹€.

public static <T> List<T> filter(List<T> list, Predicate<T> p){
    List<T> result = new ArrayList<>();
    for(T e : list){
        if(p.test(e)){
            result.add(e);
        }
    }
    return result;
}
List<Apple> redApples = filter(inventory, (Apple apple)-> RED.equals(apple.getColor()));
List<Integer> evenNumbers = filter(numbers, (Integer i) -> i%2==0);

정리 : μžλ°”μ—μ„œ λ™μž‘μ„ νŒŒλΌλ―Έν„°ν™”ν•˜λŠ” 방법

  • ν”„λ¦¬λ””μΌ€μ΄νŠΈ μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•œ 객체λ₯Ό 전달
  • 읡λͺ… 클래슀둜 감싸 ν•¨μˆ˜λ₯Ό 전달
  • λžŒλ‹€μ‹μ„ 전달
  • μ œλ„€λ¦­μ„ μ‚¬μš©

κ²°λ‘ , 'λ™μž‘'을 좔상화해 맀개인자둜 '전달' λ°›μŒ

⚠️ **GitHub.com Fallback** ⚠️