Skip to main content

Part 1 ๊ธฐ์ดˆ

About 5 minJavacrashcoursejavajdkjdk8

Part 1 ๊ธฐ์ดˆ ๊ด€๋ จ


1์žฅ - ์ž๋ฐ”8์„ ๋ˆˆ์—ฌ๊ฒจ๋ด์•ผ ํ•˜๋Š” ์ด์œ 

Stream processing: stream์ด๋ž€ ํ•œ๋ฒˆ์— ํ•œ ๊ฐœ์”ฉ ๋งŒ๋“ค์–ด์ง€๋Š” ์—ฐ์†์ ์ธ ๋ฐ์ดํ„ฐ ํ•ญ๋ชฉ๋“ค์˜ ๋ชจ์ž„์„ ๋งํ•œ๋‹ค.

๋™์ž‘ ํŒŒ๋ผ๋ฏธํ„ฐํ™”: ๋ฉ”์„œ๋“œ๋ฅผ ๋‹ค๋ฅธ ๋ฉ”์„œ๋“œ์˜ ์ธ์ˆ˜๋กœ ๋„˜๊ฒจ์ฃผ๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•œ๋‹ค.

๋ณ‘๋ ฌ์„ฑ๊ณผ ๊ณต์œ  ๊ฐ€๋ณ€ ๋ฐ์ดํ„ฐ: ๋‹ค๋ฅธ ์ฝ”๋“œ์™€ ๋™์‹œ์— ์‹คํ–‰ํ•˜๋”๋ผ๋„ ์•ˆ์ „ํ•˜๊ฒŒ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ์ฝ”๋“œ๋ฅผ ๋งŒ๋“œ๋ ค๋ฉด ๊ณต์œ ๋œ ๊ฐ€๋ณ€ ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผํ•˜์ง€ ๋ง์•„์•ผ ํ•œ๋‹ค. ์ด๋Ÿฐ ํ•จ์ˆ˜๋ฅผ pure ํ•จ์ˆ˜, stateless ํ•จ์ˆ˜๋ผ ๋ถ€๋ฅธ๋‹ค.

์ž๋ฐ” ํ•จ์ˆ˜

ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์—์„œ ํ•จ์ˆ˜๋ผ๋Š” ์šฉ์–ด๋Š” ๋ฉ”์„œ๋“œ ํŠนํžˆ ์ •์  ๋ฉ”์„œ๋“œ์™€ ๊ฐ™์€ ์˜๋ฏธ๋กœ ์‚ฌ์šฉ๋œ๋‹ค. ์ž๋ฐ”์˜ ํ•จ์ˆ˜๋Š” ์ด์— ๋”ํ•ด ์ˆ˜ํ•™์ ์ธ ํ•จ์ˆ˜์ฒ˜๋Ÿผ ์‚ฌ์šฉ๋˜๋ฉฐ ๋ถ€์ž‘์šฉ์„ ์ผ์œผํ‚ค์ง€ ์•Š๋Š” ํ•จ์ˆ˜๋ฅผ ์˜๋ฏธํ•œ๋‹ค.

์ž๋ฐ”8์—์„œ๋Š” ํ•จ์ˆ˜๋ฅผ ์ƒˆ๋กœ์šด ๊ฐ’์˜ ํ˜•์‹์œผ๋กœ ์ถ”๊ฐ€ํ–ˆ๋‹ค.(์ฆ‰, ํ•จ์ˆ˜ ์ž์ฒด๊ฐ€ ๊ฐ’)

๋ฉ”์„œ๋“œ ๋ ˆํผ๋Ÿฐ์Šค

e.g. ๋””๋ ‰ํ† ๋ฆฌ์—์„œ ๋ชจ๋“  ์ˆจ๊ฒจ์ง„ ํŒŒ์ผ์„ ํ•„ํ„ฐ๋งํ•˜๋Š” ๋ฌธ์ œ์—์„œ ์šฐ์„  ์ฃผ์–ด์ง„ ํŒŒ์ผ์ด ์ˆจ๊ฒจ์ ธ ์žˆ๋Š”์ง€ ์ฒดํฌํ•˜๋Š” ๊ธฐ๋Šฅ

File[] hiddenFiles = new File(โ€œ.โ€).listFiles(new FileFilter(){
    public boolean accept(File file){
        return file.isHidden(); //์ˆจ๊ฒจ์ง„ ํŒŒ์ผ ํ•„ํ„ฐ๋ง. 
    }
}

์œ„์˜ ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด ์ž๋ฐ”8 ์ „๊นŒ์ง€๋Š” File ํด๋ž˜์Šค์— ์ด๋ฏธ isHidden()์ด๋ผ๋Š” ๋ฉ”์„œ๋“œ๊ฐ€ ์žˆ๋Š”๋ฐ FileFilter๋กœ ๊ฐ์‹ผ ๋‹ค์Œ์— FileFilter๋ฅผ ์ธ์Šคํ„ด์Šคํ™”ํ•ด์•ผ ํ–ˆ๋‹ค.

File[] hiddenFiles = new File(โ€œ.โ€).listFiles(File::isHidden);

์ž๋ฐ”8์˜ ๋ฉ”์„œ๋“œ ๋ ˆํผ๋Ÿฐ์Šค :: (์ด ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ’์œผ๋กœ ์‚ฌ์šฉํ•˜๋ผ๋Š” ์˜๋ฏธ)๋ฅผ ์ด์šฉํ•ด์„œ listFiles()์— ์ง์ ‘ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ธฐ์กด์— ๊ฐ์ฒด ๋ ˆํผ๋Ÿฐ์Šค(new๋กœ ๊ฐ์ฒด ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ์ƒ์„ฑํ•จ)๋ฅผ ์ด์šฉํ•ด์„œ ๊ฐ์ฒด๋ฅผ ์ด๋ฆฌ์ €๋ฆฌ ์ฃผ๊ณ ๋ฐ›์•˜๋˜ ๊ฒƒ์ฒ˜๋Ÿผ ์ž๋ฐ” 8์—์„œ๋Š” File::isHidden์„ ์ด์šฉํ•ด์„œ ๋ฉ”์„œ๋“œ ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ๋งŒ๋“ค์–ด ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ๋‹ค.

๋žŒ๋‹ค: ์ต๋ช… ํ•จ์ˆ˜

ํ•จ์ˆ˜๋„ ๊ฐ’์œผ๋กœ ์ทจ๊ธ‰ํ•  ์ˆ˜ ์žˆ๋‹ค. e.g. (int x) -> x+1 : x๋ผ๋Š” ์ธ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด x+1์„ ๋ฐ˜ํ™˜ํ•˜๋ผ.

์ฝ”๋“œ ๋„˜๊ฒจ์ฃผ๊ธฐ: ์˜ˆ์ œ

Apple์ด๋ผ๋Š” ํด๋ž˜์Šค์™€ getColor()๋ผ๋Š” ๋ฉ”์„œ๋“œ๊ฐ€ ์žˆ๊ณ , Apples ๋ฆฌ์ŠคํŠธ๋ฅผ ํฌํ•จํ•˜๋Š” inventory๋ผ๋Š” ๋ณ€์ˆ˜๊ฐ€ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜์ž. ์ด๋•Œ ๋ชจ๋“  ๋…น์ƒ‰ ์‚ฌ๊ณผ๋ฅผ ์„ ํƒํ•ด์„œ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ”„๋กœ๊ทธ๋žจ์„ ๊ตฌํ˜„ํ•˜๋ ค ํ•œ๋‹ค. ์ด์ฒ˜๋Ÿผ ํŠน์ • ํ•ญ๋ชฉ์„ ์„ ํƒํ•ด์„œ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋™์ž‘์„ โ€˜ํ•„ํ„ฐ'๋ผ๊ณ  ํ•œ๋‹ค. ์ž๋ฐ”8 ์ด์ „์—๋Š” ๋‹ค์Œ์ฒ˜๋Ÿผ filterGreenApples๋ผ๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ๊ตฌํ˜„ํ–ˆ์„ ๊ฒƒ์ด๋‹ค.

public static List<Apple> filterGreenApples(List<Apple> inventory){
    List<Apple> result = new ArrayList<>();
    for (Apple apple : inventory){
        if(โ€œgreenโ€.equals(apple.getColor()){
            result.add(apple);
        }
    }
    return result; 
}

ํ•˜์ง€๋งŒ ๋ˆ„๊ตฐ๊ฐ€๋Š” ์• ํ”Œ์„ ๋ฌด๊ฒŒ๋กœ ํ•„ํ„ฐ๋ง ํ•˜๊ณ  ์‹ถ์„ ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ์ „์ฒด ์ฝ”๋“œ๋ฅผ ๋ณต๋ถ™ํ•ด์„œ ๋‹ค์Œ์ฒ˜๋Ÿผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋‹ค.

public static List<Apple> filterGreenApples(List<Apple> inventory){
    List<Apple> result = new ArrayList<>();
    for (Apple apple : inventory){
        if(apple.getWeight() > 150){
            result.add(apple);
        }
    }
    return result; 
}

์ค‘๋ณต์˜ ๋‹จ์ ์ด ๋“œ๋Ÿฌ๋‚˜๋Š” ์•ˆ์ข‹์€ ๋ฐฉ๋ฒ•์ด๋‹ค. ์ž๋ฐ”8 ์—์„œ๋Š” ์ฝ”๋“œ๋ฅผ ์ธ์ˆ˜๋กœ ๋„˜๊ฒจ์ค„ ์ˆ˜ ์žˆ์–ด์„œ filter() ๋ฉ”์„œ๋“œ๋ฅผ ์ค‘๋ณต์œผ๋กœ ๊ตฌํ˜„ํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค.

public static boolean isGreenApple(Apple apple){
    return "green".equals(apple.getColor());
}

public static boolean isHeavyApple(Apple apple){
    return apple.getWeight() > 150;
}

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

๋‹ค์Œ ์ฒ˜๋Ÿผ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœ ํ•  ์ˆ˜ ์žˆ๋‹ค.

filterApples(inventory, Apple::isGreenApple);
filterApples(inventory, Apple::isHeavyApple);

Predicate : ์ˆ˜ํ•™์—์„œ๋Š” ์ธ์ˆ˜๋กœ ๊ฐ’์„ ๋ฐ›์•„ true / false๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ Predicate๋ผ๊ณ  ํ•œ๋‹ค.

๋ฉ”์„œ๋“œ ์ „๋‹ฌ์—์„œ ๋žŒ๋‹ค๋กœ

isHeavyApple, isGreenApple์ฒ˜๋Ÿผ ํ•œ๋‘ ๋ฒˆ๋งŒ ์‚ฌ์šฉํ•  ๋ฉ”์„œ๋“œ๋ฅผ ๋งค๋ฒˆ ์ •์˜ํ•˜๋Š” ๊ฒƒ์€ ๊ท€์ฐฎ์€ ์ผ์ด๋‹ค. ์ž๋ฐ”8 ์—์„œ๋Š” ๋‹ค์Œ์ฒ˜๋Ÿผ ์ƒˆ๋กœ์šด ๊ฐœ๋…์„ ์ด์šฉํ•ด์„œ ์ฝ”๋“œ๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

filterApples(inventory, (Apple a) -> โ€œgreenโ€.equals(a.getColor());
filterApples(inventory, (Apple a) -> a.getWeight() > 150);
filterApples(inventory, (Apple a) -> a.getWeight() < 80 || โ€œbrownโ€.equals(a.getColor());

์ฆ‰, ํ•œ ๋ฒˆ๋งŒ ์‚ฌ์šฉํ•  ๋ฉ”์„œ๋“œ๋Š” ๋”ฐ๋กœ ์ •์˜๋ฅผ ๊ตฌํ˜„ํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค. ํ•˜์ง€๋งŒ ๋žŒ๋‹ค๊ฐ€ ๋ช‡ ์ค„ ์ด์ƒ์œผ๋กœ ๊ธธ์–ด์ง„๋‹ค๋ฉด(๋ณต์žกํ•œ ๋™์ž‘์„ ์ˆ˜ํ–‰ํ•˜๋Š” ์ƒํ™ฉ) ์ต๋ช… ๋žŒ๋‹ค๋ณด๋‹ค๋Š” ์ฝ”๋“œ๊ฐ€ ์ˆ˜ํ–‰ํ•˜๋Š” ์ผ์„ ์ž˜ ์„ค๋ช…ํ•˜๋Š” ์ด๋ฆ„์„ ๊ฐ€์ง„ ๋ฉ”์„œ๋“œ๋ฅผ ์ •์˜ํ•˜๊ณ  ๋ฉ”์„œ๋“œ ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ํ™œ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋ฐ”๋žŒ์งํ•˜๋‹ค. ์ฝ”๋“œ์˜ ๋ช…ํ™•์„ฑ์ด ์šฐ์„ ์‹œ ๋˜์–ด์•ผ ํ•œ๋‹ค.

์ŠคํŠธ๋ฆผ

๋‹ค์Œ์€ ๋ฆฌ์ŠคํŠธ์—์„œ ๊ณ ๊ฐ€์˜ ๊ฑฐ๋ž˜(Transcation)๋งŒ ํ•„ํ„ฐ๋งํ•œ ๋‹ค์Œ์— ํ†ตํ™”๋กœ ๊ฒฐ๊ณผ๋ฅผ ๊ทธ๋ฃนํ™”ํ•˜๋Š” ์ฝ”๋“œ๋‹ค.

Map<Currency, List<Transaction>> transactionsByCurrencies = new HashMap<>(); // ๊ทธ๋ฃนํ™”๋œ ํŠธ๋žœ์žญ์…˜์„ ๋”ํ•  Map ์ƒ์„ฑ

for (Transaction transaction : transactions){ // ํŠธ๋žœ์žญ์…˜์˜ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ฐ˜๋ณต
    if (transaction.getPrice() > 1000){ // ๊ณ ๊ฐ€์˜ ํŠธ๋žœ์žญ์…˜์„ ํ•„ํ„ฐ๋ง
        Currency currency = transaction.getCurrency(); // ํŠธ๋žœ์žญ์…˜์˜ ํ†ตํ™” ์ถ”์ถœ
        List<Transcation> transactionsForCurrency = transactionsByCurrencies.get(currency); 
        if (transactionsForCurrency == null){ // ํ˜„์žฌ ํ†ตํ™”์˜ ๊ทธ๋ฃนํ™”๋œ ๋งต์— ํ•ญ๋ชฉ์ด ์—†์œผ๋ฉด ์ƒˆ๋กœ ๋งŒ๋“ ๋‹ค.
            transactionsForCurrency = new ArrayList<>();
            transactionsByCurrencies.put(currency, transactionsForCurrency);
        }
        transactionsForCurrency.add(transaction); // ํ˜„์žฌ ํƒ์ƒ‰๋œ ํŠธ๋žœ์žญ์…˜์„ ๊ฐ™์€ ํ†ตํ™”์˜ ํŠธ๋žœ์žญ์…˜ ๋ฆฌ์ŠคํŠธ์— ์ถ”๊ฐ€ํ•œ๋‹ค. 
    }
}

์œ„ ์˜ˆ์ œ ์ฝ”๋“œ์—๋Š” ์ค‘์ฒฉ๋œ ์ œ์–ด ํ๋ฆ„ ๋ฌธ์žฅ์ด ๋งŽ์•„์„œ ์ฝ”๋“œ๋ฅผ ํ•œ ๋ฒˆ์— ์ดํ•ดํ•˜๊ธฐ ์–ด๋ ต๋‹ค. ์ŠคํŠธ๋ฆผ API๋ฅผ ์ด์š”ํ•˜๋ฉด ๋‹ค์Œ์ฒ˜๋Ÿผ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.

import static java.util.stream.Collections.toList;

Map<Currency, List<Transaction>> transactionByCurrencies = 
    transactions.stream()
            .filter((Transaction t) -> t.getPrice() > 1000) //๊ณ ๊ฐ€์˜ ํŠธ๋žœ์žญ์…˜ ํ•„ํ„ฐ๋ง
            .collect(groupingBy(Transaction::getCurrency);

์ปฌ๋ ‰์…˜์—์„œ๋Š” ๋ฐ˜๋ณต ๊ณผ์ •์„ ์ง์ ‘ ์ฒ˜๋ฆฌํ•ด์•ผ ํ–ˆ๋‹ค. ์ด๋Ÿฐ ๋ฐฉ์‹์˜ ๋ฐ˜๋ณต์„ ์™ธ๋ถ€ ๋ฐ˜๋ณต์ด๋ผ๊ณ  ํ•œ๋‹ค. ๋ฐ˜๋ฉด ์ŠคํŠธ๋ฆผ API๋ฅผ ์ด์šฉํ•˜๋ฉด ๋ฃจํ”„๋ฅผ ์‹ ๊ฒฝ์“ธ ํ•„์š”๊ฐ€ ์—†๋‹ค. ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋‚ด๋ถ€์—์„œ ๋ชจ๋“  ๋ฐ์ดํ„ฐ๊ฐ€ ์ฒ˜๋ฆฌ๋œ๋‹ค. ์ด์™€ ๊ฐ™์€ ๋ฐ˜๋ณต์„ ๋‚ด๋ถ€ ๋ฐ˜๋ณต์ด๋ผ๊ณ  ํ•œ๋‹ค.

์ปฌ๋ ‰์…˜์€ ์–ด๋–ป๊ฒŒ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๊ณ  ์ ‘๊ทผํ• ์ง€์— ์ค‘์ ์„ ๋‘๋Š” ๋ฐ˜๋ฉด ์ŠคํŠธ๋ฆผ์€ ๋ฐ์ดํ„ฐ์— ์–ด๋–ค ๊ณ„์‚ฐ์„ ํ•  ๊ฒƒ์ธ์ง€ ๋ฌ˜์‚ฌํ•˜๋Š” ๊ฒƒ์— ์ค‘์ ์„ ๋‘”๋‹ค๋Š” ์ ์„ ๊ธฐ์–ตํ•˜์ž. ์ŠคํŠธ๋ฆผ์€ ์ŠคํŠธ๋ฆผ ๋‚ด์˜ ์š”์†Œ๋ฅผ ์‰ฝ๊ฒŒ ๋ณ‘๋ ฌ๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ํ™˜๊ฒฝ์„ ์ œ๊ณตํ•œ๋‹ค๋Š” ๊ฒƒ์ด ํ•ต์‹ฌ์ด๋‹ค.

์ปฌ๋ ‰์…˜์„ ํ•„ํ„ฐ๋งํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ€์žฅ ๋น ๋ฅธ ๋ฐฉ๋ฒ•์€ ์ปฌ๋ ‰์…˜์„ ์ŠคํŠธ๋ฆผ์œผ๋กœ ๋ฐ”๊พธ๊ณ , ๋ณ‘๋ ฌ๋กœ ์ฒ˜๋ฆฌํ•œ ๋‹ค์Œ์—, ๋ฆฌ์ŠคํŠธ๋กœ ๋‹ค์‹œ ๋ณต์›ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

๋””ํดํŠธ ๋ฉ”์„œ๋“œ

๋””ํดํŠธ ๋ฉ”์„œ๋“œ๋Š” ํŠน์ • ํ”„๋กœ๊ทธ๋žจ์„ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐ ๋„์›€์„ ์ฃผ๋Š” ๊ธฐ๋Šฅ์ด ์•„๋‹ˆ๋ผ ๋ฏธ๋ž˜์— ํ”„๋กœ๊ทธ๋žจ์ด ์‰ฝ๊ฒŒ ๋ณ€ํ™”ํ•  ์ˆ˜ ์žˆ๋Š” ํ™˜๊ฒฝ์„ ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋Šฅ์ด๋‹ค.


2์žฅ - ๋™์ž‘ ํŒŒ๋ผ๋ฏธํ„ฐํ™” ์ฝ”๋“œ ์ „๋‹ฌํ•˜๊ธฐ

๋™์ž‘ ํŒŒ๋ผ๋ฏธํ„ฐํ™”๋ฅผ ์ด์šฉํ•˜๋ฉด ์ž์ฃผ ๋ฐ”๋€Œ๋Š” ์š”๊ตฌ์‚ฌํ•ญ์— ํšจ๊ณผ์ ์œผ๋กœ ๋Œ€์‘ํ•  ์ˆ˜ ์žˆ๋‹ค. ๋™์ž‘ ํŒŒ๋ผ๋ฏธํ„ฐํ™”๋ž€ ์•„์ง์€ ์–ด๋–ป๊ฒŒ ์‹คํ–‰ํ•  ๊ฒƒ์ธ์ง€ ๊ฒฐ์ •ํ•˜์ง€ ์•Š์€ ์ฝ”๋“œ ๋ธ”๋ก์„ ์˜๋ฏธํ•œ๋‹ค. ์ด ์ฝ”๋“œ ๋ธ”๋ก์€ ๋‚˜์ค‘์— ํ”„๋กœ๊ทธ๋žจ์—์„œ ํ˜ธ์ถœํ•œ๋‹ค. ์ฆ‰, ์ฝ”๋“œ ๋ธ”๋ก์˜ ์‹คํ–‰์€ ๋‚˜์ค‘์œผ๋กœ ๋ฏธ๋ค„์ง„๋‹ค. ๊ฒฐ๊ณผ์ ์œผ๋กœ ์ฝ”๋“œ ๋ธ”๋ก์— ๋”ฐ๋ผ ๋ฉ”์„œ๋“œ์˜ ๋™์ž‘์ด ํŒŒ๋ผ๋ฏธํ„ฐํ™”๋œ๋‹ค.

๋™์ž‘ ํŒŒ๋ผ๋ฏธํ„ฐํ™”

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

์„ ํƒ ์กฐ๊ฑด์„ ๊ฒฐ์ •ํ•˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค์ด๋‹ค. ์ด์™€ ๊ฐ™์€ ๋™์ž‘์„ ํ”„๋ ˆ๋””์ผ€์ดํŠธ(๋ถˆ๋ฆฐ์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜)๋ผ๊ณ  ํ•œ๋‹ค. ๋‹ค์Œ ์˜ˆ์ œ์ฒ˜๋Ÿผ ๋‹ค์–‘ํ•œ ์„ ํƒ ์กฐ๊ฑด์„ ๋Œ€ํ‘œํ•˜๋Š” ์—ฌ๋Ÿฌ ๋ฒ„์ „์˜ ApplePredicate๋ฅผ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค.

//๋ฌด๊ฑฐ์šด ์‚ฌ๊ณผ๋งŒ ์„ ํƒ
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());
    }
}

// ํ…œํ”Œ๋ฆฟ ๋ถ€๋ถ„
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;
}

ํ•˜์ง€๋งŒ ์ต๋ช… ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•ด๋„ ๋ฐ˜๋ณต๋˜์–ด ์ง€์ €๋ถ„ํ•œ ์ฝ”๋“œ๋Š” ์—ฌ์ „ํžˆ ๋งŽ๊ณ  ๋งŽ์€ ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ์ต๋ช… ํด๋ž˜์Šค์˜ ์‚ฌ์šฉ์— ์ต์ˆ™ํ•˜์ง€ ์•Š๋‹ค.

๋žŒ๋‹ค ํ‘œํ˜„์‹ ์‚ฌ์šฉ

์ž๋ฐ”8์˜ ๋žŒ๋‹ค ํ‘œํ˜„์‹์„ ์ด์šฉํ•ด์„œ ๊ฐ„๋‹จํžˆ ์žฌ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

List<Apple> result 
    = filterApples(inventory, (Apple apple) -> โ€œredโ€.equals(apple.getColor()));

๋ฆฌ์ŠคํŠธ ํ˜•์‹์œผ๋กœ ์ถ”์ƒํ™”

Apple ์ด์™ธ์˜ ๋‹ค์–‘ํ•œ ๋ฌผ๊ฑด์—์„œ ํ•„ํ„ฐ๋ง์ด ์ž‘๋™ํ•˜๋„๋ก ๋ฆฌ์ŠคํŠธ ํ˜•์‹์„ ์ถ”์ƒํ™”ํ•  ์ˆ˜ ์žˆ๋‹ค.

public interface Predicate<T>{
    boolean test(T t);
}

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<String> evenNumbers = filter(numbers, (Integer i) -> i % 2 == 0);

์‹ค์ „ ์˜ˆ์ œ - Comparator๋กœ ์ •๋ ฌํ•˜๊ธฐ

์ž๋ฐ”8์˜ List์—๋Š” sort ๋ฉ”์„œ๋“œ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ๋‹ค.(๋ฌผ๋ก  Collections.sort๋„ ์กด์žฌ) ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ฐ–๋Š” java.util.Comparator ๊ฐ์ฒด๋ฅผ ์ด์šฉํ•ด์„œ sort์˜ ๋™์ž‘์„ ํŒŒ๋ผ๋ฏธํ„ฐํ™” ํ•  ์ˆ˜ ์žˆ๋‹ค.

//java.uitl.Comparator
public interface Comparator<T>{
    public int compare(T o1, T o2);
}

Comparator๋ฅผ ๊ตฌํ˜„ํ•ด์„œ sort ๋ฉ”์„œ๋“œ์˜ ๋™์ž‘์„ ๋‹ค์–‘ํ™”ํ•  ์ˆ˜ ์žˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์ต๋ช… ํด๋ž˜์Šค๋ฅผ ์ด์šฉํ•ด์„œ ๋ฌด๊ฒŒ๊ฐ€ ์ ์€ ์ˆœ์œผ๋กœ ๋ชฉ๋ก์—์„œ ์‚ฌ๊ณผ๋ฅผ ์ •๋ ฌํ•  ์ˆ˜ ์žˆ๋‹ค.

inventory.sort(new Comparator<Apple>{
    public int compare(Apple a1, Apple a2){
        return a1.getWeight().compareTo(a2.getWeight());
    }
});

๋žŒ๋‹ค ํ‘œํ˜„์‹์„ ์ด์šฉํ•˜๋ฉด ๋‹ค์Œ์ฒ˜๋Ÿผ ๊ฐ„๋‹จํ•˜๊ฒŒ ์ฝ”๋“œ๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

inventory.sort(
    (Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight());

3์žฅ - ๋žŒ๋‹ค ํ‘œํ˜„์‹

๋žŒ๋‹ค๋ž€ ๋ฌด์—‡์ธ๊ฐ€

๋žŒ๋‹ค ํ‘œํ˜„์‹์€ ๋ฉ”์„œ๋“œ๋กœ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋Š” ์ต๋ช… ํ•จ์ˆ˜๋ฅผ ๋‹จ์ˆœํ™”ํ•œ๊ฒƒ์ด๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ๋‹ค.

Comparator<Apple> byWeight = new Comparator<Apple>() {
    public int compare(Apple a1, Apple a2) {
        return a1.getWeight().compareTo(a2.getWeight());
    }
};

Comparator<Apple> byWeight =
        (Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight());

๋žŒ๋‹ค๋Š” ์„ธ ๋ถ€๋ถ„์œผ๋กœ ์ด๋ฃจ์–ด์ง„๋‹ค.

  • ํŒŒ๋ผ๋ฏธํ„ฐ ๋ฆฌ์ŠคํŠธ : Comparator์˜ compare ๋ฉ”์„œ๋“œ์˜ ํŒŒ๋ผ๋ฏธํ„ฐ(๋‘๊ฐœ์˜ ์‚ฌ๊ณผ).
  • ํ™”์‚ดํ‘œ : ํ™”์‚ดํ‘œ(->)๋Š” ๋žŒ๋‹ค์˜ ํŒŒ๋ผ๋ฏธํ„ฐ ๋ฆฌ์ŠคํŠธ์™€ ๋ฐ”๋””๋ฅผ ๊ตฌ๋ถ„ํ•œ๋‹ค.
  • ๋žŒ๋‹ค์˜ ๋ฐ”๋”” : ๋‘ ์‚ฌ๊ณผ์˜ ๋ฌด๊ฒŒ๋ฅผ ๋น„๊ตํ•œ๋‹ค. ๋žŒ๋‹ค์˜ ๋ฐ˜ํ™˜๊ฐ’์— ํ•ด๋‹นํ•˜๋Š” ํ‘œํ˜„์‹์ด๋‹ค.

์ž๋ฐ”8์˜ ์œ ํšจํ•œ 5๊ฐ€์ง€ ๋žŒ๋‹ค ํ‘œํ˜„์‹

(String s) -> s.length()

์ฒซ ๋ฒˆ์งธ ๋žŒ๋‹ค ํ‘œํ˜„์‹์€ String ํ˜•์‹์˜ ํŒŒ๋ผ๋ฏธํ„ฐ ํ•˜๋‚˜๋ฅผ ๊ฐ€์ง€๋ฉฐ int๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ๋žŒ๋‹ค ํ‘œํ˜„์‹์—๋Š” return์ด ํ•จ์ถ•๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ return ๋ฌธ์„ ๋ช…์‹œ์ ์œผ๋กœ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค.

(Apple a) -> a.getWeight() > 150

๋‘๋ฒˆ์งธ ๋žŒ๋‹ค ํ‘œํ˜„์‹์€ Apple ํ˜•์‹์˜ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๊ฐ€์ง€๋ฉฐ boolean์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

(int x, int y) -> {
    System.out.println(โ€œResult:โ€);
    System.out.println(x+y)
};

์„ธ ๋ฒˆ์งธ ๋žŒ๋‹ค ํ‘œํ˜„์‹์€ int ํ˜•์‹์˜ ํŒŒ๋ผ๋ฏธํ„ฐ ๋‘ ๊ฐœ๋ฅผ ๊ฐ€์ง€๋ฉฐ ๋ฆฌํ„ด๊ฐ’์ด ์—†๋‹ค(void ๋ฆฌํ„ด). ์ด ์˜ˆ์ œ์—์„œ ๋ณผ ์ˆ˜ ์žˆ๋“ฏ์ด ๋žŒ๋‹ค ํ‘œํ˜„์‹์€ ์—ฌ๋Ÿฌ ํ–‰์˜ ๋ฌธ์žฅ์„ ํฌํ•จํ•  ์ˆ˜ ์žˆ๋‹ค.

() -> 42

๋„ค ๋ฒˆ์งธ ๋žŒ๋‹ค ํ‘œํ˜„์‹์€ ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ ์—†์œผ๋ฉฐ int๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

(Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight());

๋‹ค์„ฏ ๋ฒˆ์งธ ๋žŒ๋‹ค ํ‘œํ˜„์‹์€ Apple ํ˜•์‹์˜ ํŒŒ๋ผ๋ฏธํ„ฐ ๋‘ ๊ฐœ๋ฅผ ๊ฐ€์ง€๋ฉฐ int๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

//cf) ์œ ํšจํ•˜์ง€ ์•Š์€ ๋žŒ๋‹ค ํ‘œํ˜„์‹
(Integer i ) -> return โ€œAlanโ€ + i; 
(String s) -> {โ€œIron Manโ€;}

//return์€ ํ๋ฆ„ ์ œ์–ด๋ฌธ์ด๋‹ค. { } ์•ˆ์— ์žˆ์–ด์•ผ ํ•œ๋‹ค. 
(Integer i ) -> { return โ€œAlanโ€ + i }; 

//โ€œIron Manโ€์€ ๊ตฌ๋ฌธ(statement)์ด ์•„๋‹ˆ๋ผ ํ‘œํ˜„์‹(expression)์ด๋‹ค. 
(String s) -> โ€œIron Manโ€ ๋˜๋Š” (String s) -> { return โ€œIron Manโ€ }

์–ด๋””์—, ์–ด๋–ป๊ฒŒ ๋žŒ๋‹ค๋ฅผ ์‚ฌ์šฉํ• ๊นŒ?

ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค ๋ผ๋Š” ๋ฌธ๋งฅ์—์„œ ๋žŒ๋‹ค ํ‘œํ˜„์‹์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๋Š” ์ •ํ™•ํžˆ ํ•˜๋‚˜์˜ ์ถ”์ƒ ๋ฉ”์„œ๋“œ๋ฅผ ์ง€์ •ํ•˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋‹ค. ์ง€๊ธˆ๊นŒ์ง€ ์‚ดํŽด๋ณธ ์ž๋ฐ” API์˜ ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๋กœ Comparator, Runnable ๋“ฑ์ด ์žˆ๋‹ค.

//java.util.Comparator 
public interface Comparator<T>{
    int compare(T o1, T o2);
}

//java.lang.Runnable 
public interface Runnable{
    void run();
}

์ธํ„ฐํŽ˜์ด์Šค๋Š” ๋””ํดํŠธ ๋ฉ”์„œ๋“œ(์ธํ„ฐํŽ˜์ด์Šค์˜ ๋ฉ”์„œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•˜์ง€ ์•Š์€ ํด๋ž˜์Šค๋ฅผ ๊ณ ๋ คํ•ด์„œ ๊ธฐ๋ณธ ๊ตฌํ˜„์„ ์ œ๊ณตํ•˜๋Š” ๋ฐ”๋””๋ฅผ ํฌํ•จํ•˜๋Š” ๋ฉ”์„œ๋“œ)๋ฅผ ํฌํ•จํ•  ์ˆ˜ ์žˆ๋‹ค. ๋งŽ์€ ๋””ํดํŠธ ๋ฉ”์„œ๋“œ๊ฐ€ ์žˆ๋”๋ผ๋„ ์ถ”์ƒ ๋ฉ”์„œ๋“œ๊ฐ€ ์˜ค์ง ํ•˜๋‚˜๋ฉด ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๋‹ค.

๋žŒ๋‹ค ํ‘œํ˜„์‹์œผ๋กœ ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค์˜ ์ถ”์ƒ ๋ฉ”์„œ๋“œ ๊ตฌํ˜„์„ ์ง์ ‘ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์ „์ฒด ํ‘œํ˜„์‹์„ ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค์˜ ์ธ์Šคํ„ด์Šค๋กœ ์ทจ๊ธ‰(๊ธฐ์ˆ ์ ์œผ๋กœ ๋”ฐ์ง€๋ฉด ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ concrete ๊ตฌํ˜„ํ•œ ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค)ํ•  ์ˆ˜ ์žˆ๋‹ค.

ํ•จ์ˆ˜ ๋””์Šคํฌ๋ฆฝํ„ฐ

ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค์˜ ์ถ”์ƒ๋ฉ”์„œ๋“œ ์‹œ๊ทธ๋„ˆ์ฒ˜๋ฅผ ํ•จ์ˆ˜ ๋””์Šคํฌ๋ฆฝํ„ฐ๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด () -> void ๋ผ๋Š” ํ‘œ๊ธฐ๋Š” ํŒŒ๋ผ๋ฏธํ„ฐ ๋ฆฌ์ŠคํŠธ๊ฐ€ ์—†์œผ๋ฉฐ void๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ์˜๋ฏธํ•œ๋‹ค. ๋žŒ๋‹ค ํ‘œํ˜„์‹์€ ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค์˜ ์ถ”์ƒ ๋ฉ”์„œ๋“œ์™€ ๊ฐ™์€ ์‹œ๊ทธ๋‹ˆ์ฒ˜๋ฅผ ๊ฐ–๋Š”๋‹ค๋Š” ์‚ฌ์‹ค์„ ๊ธฐ์–ตํ•˜์ž.

ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ธ์ˆ˜๋ฅผ ๋ฐ›๋Š” ๋ฉ”์„œ๋“œ์—๋งŒ ๋žŒ๋‹ค ํ‘œํ˜„์‹์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

execute(() -> {});
public void execute(Runnable r){
    r.run();
}

@FunctionalInterface์€ ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค์ž„์„ ๊ฐ€๋ฆฌํ‚ค๋Š” ์• ๋…ธํ…Œ์ด์…˜์ด๋‹ค. ๋งŒ์•ฝ ์‹ค์ œ๋กœ ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ์•„๋‹ˆ๋ฉด ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์—๋Ÿฌ๋ฅผ ๋ฐœ์ƒ์‹œํ‚จ๋‹ค.

๋žŒ๋‹ค ํ™œ์šฉ: ์‹คํ–‰ ์–ด๋ผ์šด๋“œ ํŒจํ„ด

์ž์› ์ฒ˜๋ฆฌ(์˜ˆ๋ฅผ ๋“ค๋ฉด DB์˜ ํŒŒ์ผ ์ฒ˜๋ฆฌ)์— ์‚ฌ์šฉํ•˜๋Š” ์ˆœํ™˜ ํŒจํ„ด์€ ์ž์›์„ ์—ด๊ณ , ์ฒ˜๋ฆฌํ•œ ๋‹ค์Œ์—, ์ž์›์„ ๋‹ซ๋Š” ์ˆœ์„œ๋กœ ์ด๋ฃจ์–ด์ง„๋‹ค. ์„ค์ •๊ณผ ์ •๋ฆฌ ๊ณผ์ •์€ ๋Œ€๋ถ€๋ถ„ ๋น„์Šทํ•˜๋‹ค. ์ฆ‰, ์‹ค์ œ ์ž์›์„ ์ฒ˜๋ฆฌํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์„ค์ •๊ณผ ์ •๋ฆฌ ๋‘ ๊ณผ์ •์ด ๋‘˜๋Ÿฌ์‹ธ๋Š” ํ˜•ํƒœ๋ฅผ ๊ฐ–๋Š”๋ฐ ์ด ๊ฐ™์€ ํ˜•์‹์˜ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ ์–ด๋ผ์šด๋“œ ํŒจํ„ด์ด๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค.

public String processFile() throws IOException{
    try(BufferedReader br =
            new BufferedReader(new FileReader("data.txt"))){
        return br.readLine();
    }
}

์ž๋ฐ”7์— ์ƒˆ๋กœ ์ถ”๊ฐ€๋œ try-with-resources ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ–ˆ๋‹ค. ์ด๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ž์›์„ ๋ช…์‹œ์ ์œผ๋กœ ๋‹ซ์„ ํ•„์š”๊ฐ€ ์—†๋‹ค.

ํ˜„์žฌ ์ฝ”๋“œ๋Š” ํŒŒ์ผ์—์„œ ํ•œ ๋ฒˆ์— ํ•œ ์ค„๋งŒ ์ฝ์„ ์ˆ˜ ์žˆ๋‹ค. ๊ธฐ์กด์˜ ์„ค์ •, ์ •๋ฆฌ ๊ณผ์ •์€ ์žฌ์‚ฌ์šฉํ•˜๊ณ  processFile() ๋ฉ”์„œ๋“œ๋งŒ ๋‹ค๋ฅธ ๋™์ž‘์„ ๋‹ค๋ฅธ ๋™์ž‘์„ ์ˆ˜ํ–‰ํ•˜๋„๋ก ํ•ด๋ณด์ž. processFile()์˜ ๋™์ž‘์„ ํŒŒ๋ผ๋ฏธํ„ฐํ™”ํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ์ฆ‰, processFile() ๋ฉ”์„œ๋“œ๊ฐ€ BufferedReader๋ฅผ ์ด์šฉํ•ด์„œ ๋‹ค๋ฅธ ๋™์ž‘์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก processFile() ๋ฉ”์„œ๋“œ๋กœ ๋™์ž‘์„ ์ „๋‹ฌํ•ด์•ผ ํ•œ๋‹ค.

String result = processFile((BufferedReader br) -> br.readLine() + br.readLine());

ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค ์ž๋ฆฌ์— ๋žŒ๋‹ค๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ BufferedReader -> String๊ณผ IOException์„ ๋˜์งˆ ์ˆ˜ ์žˆ๋Š” ์‹œ๊ทธ๋‹ˆ์ฒ˜์™€ ์ผ์น˜ํ•˜๋Š” ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค.

@FuntionalInterface
public interface BufferedReaderProcessor{
    String process(BufferedReader b) throws IOException;
}

public String processFile(BufferedReaderProcessor p) throws IOException{
    try(BufferedReader br =
            new BufferedReader(new FileReader("data.txt"))){
        return p.process(br);
    }
}

์ด์ œ BufferedReaderProcessor์— ์ •์˜๋œ process() ๋ฉ”์„œ๋“œ์˜ ์‹œ๊ทธ๋‹ˆ์ฒ˜์™€ ์ผ์น˜ํ•˜๋Š” ๋‹ค์–‘ํ•œ ๋žŒ๋‹ค๋ฅผ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋‹ค.

String oneLine = processFile((BufferedReader br) -> br.readLine());
String twoLines = processFile((BufferedReader br) -> br.readLine() + br.readLine());

๋žŒ๋‹ค์™€ ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค ์˜ˆ์ œ

์‚ฌ์šฉ ์‚ฌ๋ก€๋žŒ๋‹ค ์˜ˆ์ œ๋Œ€์‘ํ•˜๋Š” ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค
Boolean ํ‘œํ˜„(List<String> list) -> list.isEmpty()Predicate<List<String>>
๊ฐ์ฒด ์ƒ์„ฑ() -> new Apple(10)Supplier<Apple>
๊ฐ์ฒด์—์„œ ์†Œ๋น„(Apple a) -> System.out.println(a.getWeight())Consumer<Apple>
๊ฐ์ฒด์—์„œ ์„ ํƒ/์ถ”์ถœ(String s) -> s.length()Function<String, Integer>๋˜๋Š” ToInteFunction<String>
๋‘ ๊ฐ’ ์กฐํ•ฉ(int a, int b) -> a * bIntBinaryOperator
๋‘ ๊ฐ์ฒด ๋น„๊ต(Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight())BiFunction<Apple,Apple,Integer> ๋˜๋Š” ToIntBiFunction<Apple,Apple>

์˜ˆ์™ธ, ๋žŒ๋‹ค, ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค์˜ ๊ด€๊ณ„

ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๋Š” ํ™•์ธ๋œ ์˜ˆ์™ธ๋ฅผ ๋˜์ง€๋Š” ๋™์ž‘์„ ํ—ˆ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค. ๊ทธ๋ž˜์„œ ์˜ˆ์™ธ๋ฅผ ๋˜์ง€๋ฅผ ๋žŒ๋‹ค ํ‘œํ˜„์‹์„ ๋งŒ๋“ค๋ ค๋ฉด ํ™•์ธ๋œ ์˜ˆ์™ธ๋ฅผ ์„ ์–ธํ•˜๋Š” ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ง์ ‘ ์ •์˜ํ•˜๊ฑฐ๋‚˜ ๋žŒ๋‹ค๋ฅผ try/catch ๋ธ”๋ก์œผ๋กœ ๊ฐ์‹ธ์•ผ ํ•œ๋‹ค.

@FunctionalInterface
public interface BufferedReaderProcessor{
    String process(BufferedReader b) throws IOException;
}
BufferedReaderProcessor p = (BufferedReader br) -> br.readLine();

์œ„์˜ ์˜ˆ์ œ๋Š” IOException์„ ๋ช…์‹œ์ ์œผ๋กœ ์„ ์–ธํ•˜๋Š” ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค BufferedReaderProcessor ์ด๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์šฐ๋ฆฌ๋Š” Function<T, R> ํ˜•์‹์˜ ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ธฐ๋Œ€ํ•˜๋Š” API๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์œผ๋ฉฐ ์ง์ ‘ ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋งŒ๋“ค๊ธฐ ์–ด๋ ค์šด ์ƒํ™ฉ์ด๋‹ค. ์ด๋Ÿฐ ์ƒํ™ฉ์—์„œ๋Š” ์•„๋ž˜ ์˜ˆ์ œ์ฒ˜๋Ÿผ ๋ช…์‹œ์ ์œผ๋กœ ํ™•์ธ๋œ ์˜ˆ์™ธ๋ฅผ ์žก์„ ์ˆ˜ ์žˆ๋‹ค.

Function<BufferedReader, String> f = 
    (BufferedReader b) -> {
        try{
            return b.readLine();
        }
        catch(IOException e){
            throw new RuntimeException(e);
        }
    };

ํ˜•์‹ ๊ฒ€์‚ฌ, ํ˜•์‹ ์ถ”๋ก , ์ œ์•ฝ

๋žŒ๋‹ค ํ‘œํ˜„์‹ ์ž์ฒด์—๋Š” ๋žŒ๋‹ค๊ฐ€ ์–ด๋–ค ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๋Š”์ง€์˜ ์ •๋ณด๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์ง€ ์•Š๋‹ค. ๋žŒ๋‹ค๊ฐ€ ์‚ฌ์šฉ๋˜๋Š” context๋ฅผ ์ด์šฉํ•ด์„œ ๋žŒ๋‹ค์˜ ํ˜•์‹(type)์„ ์ถ”๋ก ํ•  ์ˆ˜ ์žˆ๋‹ค.

๋žŒ๋‹ค ํ‘œํ˜„์‹์˜ ํ˜•์‹ ๊ฒ€์‚ฌ ๊ณผ์ •์˜ ์žฌ๊ตฌ์„ฑ
๋žŒ๋‹ค ํ‘œํ˜„์‹์˜ ํ˜•์‹ ๊ฒ€์‚ฌ ๊ณผ์ •์˜ ์žฌ๊ตฌ์„ฑ

ํŠน๋ณ„ํ•œ void ํ˜ธํ™˜ ๊ทœ์น™

๋žŒ๋‹ค์˜ ๋ฐ”๋””์— ์ผ๋ฐ˜ ํ‘œํ˜„์‹์ด ์žˆ์œผ๋ฉด void๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜ ๋””์Šคํฌ๋ฆฝํ„ฐ์™€ ํ˜ธํ™˜๋œ๋‹ค(๋ฌผ๋ก  ํŒŒ๋ผ๋ฏธํ„ฐ ๋ฆฌ์ŠคํŠธ๋„ ํ˜ธํ™˜๋˜์–ด์•ผ ํ•จ). ์˜ˆ๋ฅผ ๋“ค์–ด List์˜ add ๋ฉ”์„œ๋“œ๋Š” boolean์„ ๋ฐ˜ํ™˜ํ•˜์ง€๋งŒ Consumer ์ปจํ…์ŠคํŠธ(T -> void)์—๋„ ์œ ํšจํ•œ ์ฝ”๋“œ๋‹ค.

// Predicate๋Š” ๋ถˆ๋ฆฐ ๋ฐ˜ํ™˜๊ฐ’์„ ๊ฐ–๋Š”๋‹ค.
Predicate<String> p = s -> list.add(s);
// Consumer๋Š” void ๋ฐ˜ํ™˜๊ฐ’์„ ๊ฐ–๋Š”๋‹ค. 
Consumer<String> b = s -> list.add(s);

ํ˜•์‹ ์ถ”๋ก 

//ํ˜•์‹์„ ์ถ”๋ก ํ•˜์ง€ ์•Š์Œ
Comparator<Apple> c = (Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight());
//ํ˜•์‹์„ ์ถ”๋ก ํ•จ
Comparator<Apple> c = (a1,  a2) -> a1.getWeight().compareTo(a2.getWeight());

//ํ˜•์‹ ์ถ”๋ก ํ•œ ๋‹ค๋ฅธ ์˜ˆ์ œ
List<Apple> greenApples = filter(inventory, a -> โ€œgreenโ€.equals(a.getColor()));

์ง€์—ญ ๋ณ€์ˆ˜ ์‚ฌ์šฉ

๋žŒ๋‹ค ํ‘œํ˜„์‹์—์„œ๋Š” ์ž์œ  ๋ณ€์ˆ˜(ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋„˜๊ฒจ์ง„ ๋ณ€์ˆ˜๊ฐ€ ์•„๋‹ˆ๋ผ ์™ธ๋ถ€์—์„œ ์ •์˜๋œ ๋ณ€์ˆ˜)๋ฅผ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด์™€ ๊ฐ™์€ ๋™์ž‘์„ ๋žŒ๋‹ค ์บก์ณ๋ง์ด๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค.

int portNumber = 123;
Runnable r = () -> System.out.println(portNumber);

ํ•˜์ง€๋งŒ ์ž์œ  ๋ณ€์ˆ˜์—๋„ ์•ฝ๊ฐ„์˜ ์ œ์•ฝ์ด ์žˆ๋‹ค. ๋žŒ๋‹ค๋Š” ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜์™€ ์ •์  ๋ณ€์ˆ˜๋ฅผ ์ž์œ ๋กญ๊ฒŒ ์บก์ณ(์ž์‹ ์˜ ๋ฐ”๋””์—์„œ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ๋„๋ก) ํ•  ์ˆ˜ ์žˆ๋‹ค. ํ•˜์ง€๋งŒ ๊ทธ๋Ÿฌ๋ ค๋ฉด ์ง€์—ญ ๋ณ€์ˆ˜๋Š” final๋กœ ์„ ์–ธ๋˜๊ฑฐ๋‚˜ ์‹ค์งˆ์ ์œผ๋กœ final ์ฒ˜๋Ÿผ ์ทจ๊ธ‰๋˜์–ด์•ผ ํ•œ๋‹ค.

//์ปดํŒŒ์ผ ์—๋Ÿฌ
int portNumber = 123;
Runnable r = () -> System.out.println(portNumber);
portNumber = 321;

์ง€์—ญ๋ณ€์ˆ˜์— ์™œ ์ด๋Ÿฌํ•œ ์ œ์•ฝ์ด ํ•„์š”ํ•œ์ง€ ์•Œ์•„๋ณด์ž.

์šฐ์„  ๋‚ด๋ถ€์ ์œผ๋กœ ์ง€์—ญ ๋ณ€์ˆ˜๋Š” ์Šคํƒ์— ์œ„์น˜ํ•œ๋‹ค. ๋žŒ๋‹ค์—์„œ ์ง€์—ญ ๋ณ€์ˆ˜์— ๋ฐ”๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฐ€์ • ํ•˜์— ๋žŒ๋‹ค๊ฐ€ ์Šค๋ ˆ๋“œ์—์„œ ์‹คํ–‰๋œ๋‹ค๋ฉด ๋ณ€์ˆ˜๋ฅผ ํ• ๋‹นํ•œ ์Šค๋ ˆ๋“œ๊ฐ€ ์‚ฌ๋ผ์ ธ์„œ ๋ณ€์ˆ˜ ํ• ๋‹น์ด ํ•ด์ œ๋˜์—ˆ๋Š”๋ฐ๋„ ๋žŒ๋‹ค๋ฅผ ์‹คํ–‰ํ•˜๋Š” ์Šค๋ ˆ๋“œ์—์„œ๋Š” ํ•ด๋‹น ๋ณ€์ˆ˜์— ์ ‘๊ทผํ•˜๋ ค ํ•  ์ˆ˜ ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ž๋ฐ” ๊ตฌํ˜„์—์„œ๋Š” ์›๋ž˜ ๋ณ€์ˆ˜์— ์ ‘๊ทผ์„ ํ—ˆ์šฉํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์ž์œ  ์ง€์—ญ ๋ณ€์ˆ˜์˜ ๋ณต์‚ฌ๋ณธ์„ ์ œ๊ณตํ•œ๋‹ค. ๋”ฐ๋ผ์„œ ๋ณต์‚ฌ๋ณธ์˜ ๊ฐ’์ด ๋ฐ”๋€Œ์ง€ ์•Š์•„์•ผ ํ•˜๋ฏ€๋กœ ์ง€์—ญ ๋ณ€์ˆ˜์—๋Š” ํ•œ ๋ฒˆ๋งŒ ๊ฐ’์„ ํ• ๋‹นํ•ด์•ผ ํ•œ๋‹ค๋Š” ์ œ์•ฝ์ด ์ƒ๊ธด๊ฒƒ์ด๋‹ค.

๋žŒ๋‹ค์™€ ์ต๋ช… ํด๋ž˜์Šค ๋ชจ๋‘ ๋ฉ”์„œ๋“œ์˜ ์ธ์ˆ˜๋กœ ์ „๋‹ฌ๋  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์ž์‹ ์˜ ์™ธ๋ถ€ ์˜์—ญ์˜ ๋ณ€์ˆ˜์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค. ๋‹ค๋งŒ ๋žŒ๋‹ค์™€ ์ต๋ช… ํด๋ž˜์Šค๋Š” ๋žŒ๋‹ค๊ฐ€ ์ •์˜๋œ ๋ฉ”์„œ๋“œ์˜ ์ง€์—ญ ๋ณ€์ˆ˜์˜ ๊ฐ’์€ ๋ฐ”๊ฟ€ ์ˆ˜ ์—†๋‹ค. ๋žŒ๋‹ค๊ฐ€ ์ •์˜๋œ ๋ฉ”์„œ๋“œ์˜ ์ง€์—ญ ๋ณ€์ˆซ๊ฐ’์€ final ๋ณ€์ˆ˜์—ฌ์•ผ ํ•œ๋‹ค. ๋žŒ๋‹ค๋Š” ๋ณ€์ˆ˜๊ฐ€ ์•„๋‹Œ ๊ฐ’์— ๊ตญํ•œ๋˜์–ด ์–ด๋–ค ๋™์ž‘์„ ์ˆ˜ํ–‰ํ•œ๋‹ค๋Š” ์‚ฌ์‹ค์ด ๋ช…ํ™•ํ•ด์ง„๋‹ค. ์ง€์—ญ ๋ณ€์ˆซ๊ฐ’์€ ์Šคํƒ์— ์กด์žฌํ•˜๋ฏ€๋กœ ์ž์‹ ์„ ์ •์˜ํ•œ ์Šค๋ ˆ๋“œ์™€ ์ƒ์กด์„ ๊ฐ™์ด ํ•ด์•ผ ํ•˜๋ฉฐ ๋”ฐ๋ผ์„œ ์ง€์—ญ ๋ณ€์ˆ˜๋Š” final ์ด์–ด์•ผ ํ•œ๋‹ค. ๊ฐ€๋ณ€ ์ง€์—ญ ๋ณ€์ˆ˜๋ฅผ ์ƒˆ๋กœ์šด ์Šค๋ ˆ๋“œ์—์„œ ์บก์ณํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด ์•ˆ์ „ํ•˜์ง€ ์•Š์€ ๋™์ž‘์„ ์ˆ˜ํ–‰ํ•  ๊ฐ€๋Šฅ์„ฑ์ด ์ƒ๊ธด๋‹ค(์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜๋Š” ์Šค๋ ˆ๋“œ๊ฐ€ ๊ณต์œ ํ•˜๋Š” ํž™์— ์กด์žฌํ•˜๋ฏ€๋กœ ํŠน๋ณ„ํ•œ ์ œ์•ฝ์ด ์—†๋‹ค).

๋ฉ”์„œ๋“œ ๋ ˆํผ๋Ÿฐ์Šค

๋ฉ”์„œ๋“œ ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ์ด์šฉํ•˜๋ฉด ๊ธฐ์กด์˜ ๋ฉ”์„œ๋“œ ์ •์˜๋ฅผ ์žฌํ™œ์šฉํ•ด์„œ ๋žŒ๋‹ค์ฒ˜๋Ÿผ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋‹ค. ๋•Œ๋กœ๋Š” ๋ฉ”์„œ๋“œ ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋” ๊ฐ€๋…์„ฑ์ด ์ข‹์œผ๋ฉฐ ์ž์—ฐ์Šค๋Ÿฌ์šธ ์ˆ˜ ์žˆ๋‹ค.

// ๊ธฐ์กด ์ฝ”๋“œ
inventory.sort((Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight()));

// ๋ฉ”์„œ๋“œ ๋ ˆํผ๋Ÿฐ์Šค์™€ java.util.Comparator.comparing์„ ํ™œ์šฉํ•œ ์ฝ”๋“œ 
inventory.sort((comparing(Apple::getWeight());

๋ฉ”์„œ๋“œ ๋ ˆํผ๋Ÿฐ์Šค๋Š” ํŠน์ • ๋ฉ”์„œ๋“œ๋งŒ์„ ํ˜ธ์ถœํ•˜๋Š” ๋žŒ๋‹ค์˜ ์ถ•์•ฝํ˜•์ด๋ผ๊ณ  ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด Apple::getWeight๋Š” Apple ํด๋ž˜์Šค์— ์ •์˜๋œ getWeight์˜ ๋ฉ”์„œ๋“œ ๋ ˆํผ๋Ÿฐ์Šค๋‹ค. ์‹ค์ œ๋กœ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋ฏ€๋กœ ๊ด„ํ˜ธ๋Š” ํ•„์š”์—†๋‹ค. ๊ฒฐ๊ณผ์ ์œผ๋กœ ๋ฉ”์„œ๋“œ ๋ ˆํผ๋Ÿฐ์Šค๋Š” ๋žŒ๋‹ค ํ‘œํ˜„์‹ (Apple a) -> a.getWeight()๋ฅผ ์ถ•์•ฝํ•œ ๊ฒƒ์ด๋‹ค.

๋žŒ๋‹ค์™€ ๋ฉ”์„œ๋“œ ๋ ˆํผ๋Ÿฐ์Šค ๋‹จ์ถ• ํ‘œํ˜„ ์˜ˆ์ œ

๋žŒ๋‹ค๋ฉ”์„œ๋“œ ๋ ˆํผ๋Ÿฐ์Šค ๋‹จ์ถ• ํ‘œํ˜„
(Apple a) -> a.getWeight()Apple::getWeight
() -> Thread.currentThread().dumpStack()Thread.currentThread()::dumpStack
(str, i) -> str.substring(i)String::substring
(String s) -> System.out.println(s)System.out::println

๋ฉ”์„œ๋“œ ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•

a
a

๋ฉ”์„œ๋“œ ๋ ˆํผ๋Ÿฐ์Šค๋Š” ์„ธ ๊ฐ€์ง€ ์œ ํ˜•์œผ๋กœ ๊ตฌ๋ถ„ํ•  ์ˆ˜ ์žˆ๋‹ค. โ€˜์ •์  ๋ฉ”์„œ๋“œ ๋ ˆํŽ˜๋Ÿฐ์Šคโ€™, โ€˜๋‹ค์–‘ํ•œ ํ˜•์‹์˜ ์ธ์Šคํ„ด์Šค ๋ฉ”์„œ๋“œ ๋ ˆํผ๋Ÿฐ์Šคโ€™, โ€˜๊ธฐ์กด ๊ฐ์ฒด์˜ ์ธ์Šคํ„ด์Šค ๋ฉ”์„œ๋“œ ๋ ˆํผ๋Ÿฐ์Šค'

์ƒ์„ฑ์ž ๋ ˆํผ๋Ÿฐ์Šค

ClassName::new ์ฒ˜๋Ÿผ ํด๋ž˜์Šค๋ช…๊ณผ new ํ‚ค์›Œ๋“œ๋ฅผ ์ด์šฉํ•ด์„œ ๊ธฐ์กด ์ƒ์„ฑ์ž์˜ ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.

Supplier<Apple> c1 = Apple :: new; // ๋””ํดํŠธ ์ƒ์„ฑ์ž Apple()์˜ ์ƒ์„ฑ์ž ๋ ˆํผ๋Ÿฐ์Šค
Apple a1 = c1.get(); // Supplier์˜ get ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ด์„œ ์ƒˆ๋กœ์šด Apple ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.

// ์œ„ ์˜ˆ์ œ๋Š” ๋‹ค์Œ ์ฝ”๋“œ์™€ ๊ฐ™๋‹ค.
Supplier<Apple> c1 = () -> new Apple(); // ๋žŒ๋‹ค ํ‘œํ˜„์‹์€ ๋””ํดํŠธ ์ƒ์„ฑ์ž๋ฅผ ๊ฐ€์ง„ Apple์„ ๋งŒ๋“ ๋‹ค.
Apple a1 = c1.get(); // Supplier์˜ get ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ด์„œ ์ƒˆ๋กœ์šด Apple ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.

Apple(Integer weight) ๋ผ๋Š” ์‹œ๊ทธ๋‹ˆ์ฒ˜๋ฅผ ๊ฐ–๋Š” ์ƒ์„ฑ์ž๋Š” Function ์ธํ„ฐํŽ˜์ด์Šค์˜ ์‹œ๊ทธ๋‹ˆ์ฒ˜์™€ ๊ฐ™๋‹ค.

Function<Integer, Apple> c2 = Apple :: new; // Apple (Integer weight)์˜ ์ƒ์„ฑ์ž ๋ ˆํผ๋Ÿฐ์Šค
Apple a2 = c2.apply(110); // Function์˜ apply ๋ฉ”์„œ๋“œ๋ฅผ ๋ฌด๊ฒŒ๋ฅผ ์ธ์ˆ˜๋กœ ํ˜ธ์ถœํ•ด์„œ ์ƒˆ๋กœ์šด Apple ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.

//์œ„ ์˜ˆ์ œ๋Š” ๋‹ค์Œ ์ฝ”๋“œ์™€ ๊ฐ™๋‹ค.
Function<Integer, Apple> c2 = (weight) -> new Apple(weight); // ํŠน์ • ๋ฌด๊ฒŒ์˜ ์‚ฌ๊ณผ๋ฅผ ๋งŒ๋“œ๋Š” ๋žŒ๋‹ค ํ‘œํ˜„์‹
Apple a2 = c2.apply(110); // Function์˜ apply ๋ฉ”์„œ๋“œ๋ฅผ ๋ฌด๊ฒŒ๋ฅผ ์ธ์ˆ˜๋กœ ํ˜ธ์ถœํ•ด์„œ ์ƒˆ๋กœ์šด Apple ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.

๋žŒ๋‹ค, ๋ฉ”์„œ๋“œ ๋ ˆํผ๋Ÿฐ์Šค ํ™œ์šฉํ•˜๊ธฐ

// 1๋‹จ๊ณ„ 
public class AppleComparator implements Comparator<Apple>{
    public int compare(Apple a1, Apple a2){
        return a1.getWeight().compareTo(a2.getWeight());
    }
}
inventory.sort(new AppleComparator());

// 2๋‹จ๊ณ„: ์ต๋ช… ํด๋ž˜์Šค ์‚ฌ์šฉ
inventory.sort(new Comparator<Apple>(){
    public int compare(Apple a1, Apple a2){
        return a1.getWeight().compareTo(a2.getWeight());
    }
});

// 3๋‹จ๊ณ„ : ๋žŒ๋‹ค ํ‘œํ˜„์‹ ์‚ฌ์šฉ
inventory.sort((Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight()));

//ํ˜•์‹ ์ถ”๋ก ์„ ํ†ตํ•ด ๋” ๊ฐ„์†Œํ™”
inventory.sort((a1,  a2) -> a1.getWeight().compareTo(a2.getWeight()));

 inventory.sort(comparing((a) -> a.getWeight()));

// 4๋‹จ๊ณ„ : ๋ฉ”์„œ๋“œ ๋ ˆํผ๋Ÿฐ์Šค ์‚ฌ์šฉ
inventory.sort(comparing(Apple::getWeight));

๋žŒ๋‹ค ํ‘œํ˜„์‹์„ ์กฐํ•ฉํ•  ์ˆ˜ ์žˆ๋Š” ์œ ์šฉํ•œ ๋ฉ”์„œ๋“œ

์—ฌ๋Ÿฌ ๊ฐœ์˜ ๋žŒ๋‹ค ํ‘œํ˜„์‹์„ ์กฐํ•ฉํ•ด์„œ ๋ณต์žกํ•œ ๋žŒ๋‹ค ํ‘œํ˜„์‹์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค(๋””ํดํŠธ ๋ฉ”์„œ๋“œ ๋•๋ถ„).

Comparator ์กฐํ•ฉ

// ์—ญ์ •๋ ฌ
inventory.sort(comparing(Apple::getWeight)).reversed();

// Comparator ์—ฐ๊ฒฐ
inventory.sort(comparing(Apple::getWeight).reversed().thenComparing(Apple::getCountry));

Predicate ์กฐํ•ฉ

// ๋ฐ˜์ „์‹œํ‚ด
Predicate<Apple> notRedApple = redApple.negate();

// and ์กฐํ•ฉ
Predicate<Apple> redAndHeavyApple = redApple.and(a -> a.getWeight() > 150);

a.or(b).and(c)๋Š” (a || b) && c ์™€ ๊ฐ™๋‹ค.

Function ์กฐํ•ฉ

// andThen - ์ฃผ์–ด์ง„ ํ•จ์ˆ˜๋ฅผ ๋จผ์ € ์ ์šฉํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋‹ค๋ฅธ ํ•จ์ˆ˜์˜ ์ž…๋ ฅ์œผ๋กœ ์ „๋‹ฌํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜
Function<Integer, Integer> f = x -> x+1;
Function<Integer, Integer> g = x -> x*2;
Function<Integer, Integer> h = f.andThen(g);;
int result = h.apply(1); // 4๋ฅผ ๋ฐ˜ํ™˜ 

//compose - ์ธ์ž๋กœ ์ฃผ์–ด์ง„ ํ•จ์ˆ˜๋ฅผ ๋จผ์ € ์‹คํ–‰ํ•œ ๋‹ค์Œ์— ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ์™ธ๋ถ€ ํ•จ์ˆ˜์˜ ์ธ์ˆ˜๋กœ ์ œ๊ณต
Function<Integer, Integer> f = x -> x+1;
Function<Integer, Integer> g = x -> x*2;
Function<Integer, Integer> h = f.compose(g);;
int result = h.apply(1); // 3๋ฅผ ๋ฐ˜ํ™˜

์ด์ฐฌํฌ (MarkiiimarK)
Never Stop Learning.