DevLog ๐Ÿ˜ถ

[๋ชจ๋˜์ž๋ฐ”์ธ์•ก์…˜] ์ž๋ฐ” 8๋กœ ์˜ค๋ฉด์„œ ์ƒ๊ธด ์ผ ๋ณธ๋ฌธ

๐Ÿ“–/Modern Java in Action

[๋ชจ๋˜์ž๋ฐ”์ธ์•ก์…˜] ์ž๋ฐ” 8๋กœ ์˜ค๋ฉด์„œ ์ƒ๊ธด ์ผ

dolmeng2 2023. 2. 23. 22:31

๐Ÿ’ฌ ๋ชจ๋˜ ์ž๋ฐ” ์ธ ์•ก์…˜ ์ฑ•ํ„ฐ 1์„ ์ฝ๊ณ  ์ •๋ฆฌํ•œ ๊ธ€์ž…๋‹ˆ๋‹ค. 

 


โœ”๏ธ ์ž๋ฐ” ํ•จ์ˆ˜

์ž๋ฐ”์—์„œ ํ”ํžˆ 'ํ•จ์ˆ˜', ๊ทธ๋ฆฌ๊ณ  '๋ฉ”์„œ๋“œ'๋ผ๋Š” ์ด๋ฆ„์„ ๋งŽ์ด ๋“ค์„ ์ˆ˜ ์žˆ๋‹ค.

์Šคํ„ฐ๋””์—์„œ ํฌ๋ฃจ๋ถ„์ด ํ•จ์ˆ˜์™€ ๋ฉ”์„œ๋“œ์— ๋Œ€ํ•ด์„œ ์ •์˜๋ฅผ ํ•ด์ฃผ์…จ๋Š”๋ฐ, ํฌ๊ฒŒ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ๋‹ค.

 

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

 

๊ทธ ์™ธ์— ํ•จ์ˆ˜๋Š” '๋…๋ฆฝ์ ์œผ๋กœ ์กด์žฌํ•˜๋ฉฐ, ํ•˜๋‚˜์˜ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๋„๋ก ๊ตฌ์„ฑํ•œ ๊ฒƒ'์ด๋ฉฐ, ๋ฉ”์„œ๋“œ๋Š” 'ํด๋ž˜์Šค ๋‚ด๋ถ€์— ์ •์˜๋˜์–ด, ๊ฐ์ฒด์˜ ์†์„ฑ์„ ๋‹ค๋ฃจ๊ธฐ ์œ„ํ•œ ํ–‰์œ„'๋ผ๊ณ ๋„ ํ•˜๋Š”๋ฐ ๋…๋ฆฝ์ ์ธ์ง€, ์ข…์†์ ์ธ์ง€์— ๋”ฐ๋ฅธ๋‹ค๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

 

โœ”๏ธ ์ผ๊ธ‰ ๊ฐ์ฒด (First-class)

์šฐ๋ฆฌ๋Š” ๋ณดํ†ต ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ํ•  ๋•Œ, '์ผ๊ธ‰ ๊ฐ์ฒด'๋ผ๋Š” ๋ง์„ ๋“ค์–ด๋ณธ ์ ์ด ์žˆ์„ ๊ฒƒ์ด๋‹ค. ์ผ๊ธ‰ ๊ฐ์ฒด๋Š” ๋‹ค๋ฅธ ๊ฐ์ฒด๋“ค์— ๋Œ€ํ•ด '์ผ๋ฐ˜์ ์œผ๋กœ ์ ์šฉ ๊ฐ€๋Šฅํ•œ ์—ฐ์‚ฐ์„ ๋ชจ๋‘ ์ง€์›ํ•˜๋Š” ๊ฐ์ฒด'๋ฅผ ์˜๋ฏธํ•œ๋‹ค. ๋‹จ์ˆœํžˆ ์ด ๋ฌธ์žฅ์„ ๋ณด๋ฉด ๋ฌด์Šจ ์†Œ๋ฆฌ์ธ์ง€ ์ดํ•ดํ•˜๊ธฐ ์–ด๋ ต๋‹ค. ์—ฌ๊ธฐ์„œ ๋งํ•˜๋Š” '์ผ๋ฐ˜์ ์œผ๋กœ ์ ์šฉ ๊ฐ€๋Šฅํ•œ ์—ฐ์‚ฐ'์ด๋ผ๋Š” ๊ฒŒ ๋ฌด์—‡์„๊นŒ?

1. ๋ณ€์ˆ˜๋‚˜ ๋ฐ์ดํ„ฐ์— ๊ฐ’์„ ํ• ๋‹นํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค.
2. ๊ฐ์ฒด์˜ ์ธ์ž๋กœ ๋„˜๊ธธ ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค.
3. ๊ฐ์ฒด์˜ ๋ฆฌํ„ด๊ฐ’์œผ๋กœ ๋ฆฌํ„ดํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค.

๊ทธ๋Ÿผ, ๊ฐ๊ฐ์˜ ์š”์†Œ๋“ค์— ๋Œ€ํ•ด์„œ ์ž˜ ์ƒ๊ฐํ•ด๋ณด์ž. ์ž๋ฐ”์˜ ๋ฉ”์„œ๋“œ๋Š” ์™œ ์ผ๊ธ‰ ๊ฐ์ฒด๋ผ๊ณ  ํ•  ์ˆ˜ ์—†์„๊นŒ?

public class Test {
    public static void main(String[] args) {
        // ๋ฉ”์„œ๋“œ๋ฅผ ๋ณ€์ˆ˜์— ํ• ๋‹นํ•  ์ˆ˜ ์—†๋‹ค.
        Object value = sample;
    }

    public static void sample() {
        System.out.println("I'm Sample!");
    }
}

์ž๋ฐ”์—์„œ ๋ฉ”์„œ๋“œ ๊ทธ ์ž์ฒด๋ฅผ ๋ณ€์ˆ˜ ์ž์ฒด์— ํ• ๋‹นํ•˜๋Š” ๊ฒƒ์„ ๋ณธ ์  ์—†์„ ๊ฒƒ์ด๋‹ค. ๋ฉ”์„œ๋“œ์˜ ๋ฆฌํ„ด ๊ฐ’์ด ์•„๋‹Œ, ๋ฉ”์„œ๋“œ ๊ทธ ์ž์ฒด๋ฅผ ํ• ๋‹นํ•˜๋Š” ๊ฒƒ์€ ๋ถˆ๊ฐ€๋Šฅํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

public class Test {
    public static void main(String[] args) {
        // ๋ฉ”์„œ๋“œ ์ž์ฒด๋ฅผ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์ „๋‹ฌํ•  ์ˆ˜ ์—†๋‹ค.
        hello((Object) sample);
    }

    public static String hello(Object method) {
    	...
    }

    public static void sample() {
        System.out.println("I'm Sample!");
    }
}
public class Test {
    public static String hello() {
        return sample;
    }

    public static String sample() {
        return "Sample!";
    }
}

๋˜ํ•œ, ๋ฉ”์„œ๋“œ ๊ทธ ์ž์ฒด๋ฅผ ํ•จ์ˆ˜์˜ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ „๋‹ฌํ•  ์ˆ˜ ์—†์œผ๋ฉฐ, ๋ฉ”์„œ๋“œ์˜ ๋ฆฌํ„ด ๊ฐ’์œผ๋กœ ๋ฐ”๋กœ ๋ฐ˜ํ™˜ํ•  ์ˆ˜๋„ ์—†๋‹ค.

 

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

์•ž์œผ๋กœ ๋ณธ ์ฑ…์„ ํ•™์Šตํ•˜๋ฉด์„œ ๊ฐ๊ฐ์— ๋Œ€ํ•ด ํ•™์Šตํ•  ์˜ˆ์ •์ด๊ธฐ ๋•Œ๋ฌธ์—, ์—ฌ๊ธฐ์„œ๋Š” ์ด์ •๋„๋งŒ ๊ฐ„๋žตํ•˜๊ฒŒ ์„ค๋ช…ํ•˜๊ณ  ๋„˜์–ด๊ฐ€๋„๋ก ํ•˜๊ฒ ๋‹ค ๐Ÿฅน


โœ”๏ธ ์ž๋ฐ” 8์—์„œ์˜ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ

- ์ž๋ฐ” 8์—์„œ๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ’์ฒ˜๋Ÿผ, ์ผ๊ธ‰ ๊ฐ์ฒด๋กœ ์ทจ๊ธ‰ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•œ๋‹ค. ์ด๋Ÿฌํ•œ ๊ธฐ๋Šฅ์„ '๋ฉ”์„œ๋“œ ์ฐธ์กฐ'๋ผ๊ณ  ํ•œ๋‹ค.

File[] hiddenFiles = new File(".").listFiles(new FileFilter() {
public boolean accept(File file) {
        return file.isHidden();
        }
        });

 

์œ„ ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด, ๊ธฐ์กด์—๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋ฉ”์„œ๋“œ๋ฅผ ์ „๋‹ฌํ•ด์ฃผ๊ธฐ ์œ„ํ•ด์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ธด ๊ตฌํ˜„์ฒด๋ฅผ ํ•จ๊ป˜ ์„ ์–ธํ•ด์„œ ๋ณด๋‚ด์ฃผ๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ์œ„ ์ฝ”๋“œ๋ฅผ ๋ฉ”์„œ๋“œ ์ฐธ์กฐ๋ฅผ ํ†ตํ•ด์„œ ์ˆ˜์ •ํ•ด๋ณด์ž.

File[] hiddenFiles = new File(".").listFiles(File::isHidden);

๋‹ค์Œ๊ณผ ๊ฐ™์ด ::๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋ฉ”์„œ๋“œ ์ฐธ์กฐ๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๋งˆ์น˜ '๊ฐ’'์„ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๊ฐ„๊ฒฐํ•˜๊ฒŒ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

์ฆ‰, ::๋Š” ‘ํ•ด๋‹น ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ’์œผ๋กœ ์‚ฌ์šฉํ•˜๋ผ’๋Š” ์˜๋ฏธ๋กœ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

 

๋˜ํ•œ, ๋žŒ๋‹ค์‹์„ ํ™œ์šฉํ•˜์—ฌ ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ’์ฒ˜๋Ÿผ ์ทจ๊ธ‰ํ•  ์ˆ˜ ์žˆ๋‹ค. ์žฌ์‚ฌ์šฉ์„ฑ์ด ์—†๊ณ  ๊ฐ„๋‹จํ•œ ์ฝ”๋“œ์˜ ๊ฒฝ์šฐ ๋žŒ๋‹ค๋ฅผ ํ™œ์šฉํ•˜์ž.

(int x) -> x + 1


โœ”๏ธ ๋™์ž‘ ํŒŒ๋ผ๋ฏธํ„ฐํ™” ์ดํ•ดํ•˜๊ธฐ

๋™์ž‘ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์•Œ์•„๋ณด๊ธฐ ์ „์—, ๊ฐ„๋‹จํ•œ ์˜ˆ์ œ๋ฅผ ์‚ดํŽด๋ณด์ž. ์•„๋ž˜ ์˜ˆ์ œ๋Š” ์ดˆ๋ก์ƒ‰ ์‚ฌ๊ณผ์— ๋Œ€ํ•ด์„œ ํ•„ํ„ฐ๋ง์„ ์ง„ํ–‰ํ•˜๋Š” ์ฝ”๋“œ์ด๋‹ค.

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 boolean isGreenApple(Apple apple) {
        return GREEN.equals(apple.getColor());
        }

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

static List<Apple> filterApples(List<Apple> inventory,
        Predicate<Apple> p) {
        List<Apple> result = new ArrayList<>();
        for (Apple apple: inventory) {
        if (p.test(apple)) { // p์— ๋Œ€ํ•œ ์กฐ๊ฑด ๊ฒ€์ฆ
        result.add(apple);
        }
        }
        return result;
        }

Predicate๋ฅผ ํ™œ์šฉํ•ด์„œ ๋งˆ์น˜, ์ „๋žต ํŒจํ„ด์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ์ฃผ์ž…์„ ๋ฐ›์•„์„œ ์กฐ๊ฑด์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค. ๋ณธ ์ฑ…์—์„œ๋Š” Predicate๋ฅผ

'์ธ์ˆ˜๋กœ ๊ฐ’์„ ๋ฐ›์•„ true ํ˜น์€ false๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜'๋ผ๊ณ  ํ‘œํ˜„ํ•˜์˜€๋‹ค. ์ด ๋‚ด์šฉ์€ Chapter 2์—์„œ ์กฐ๊ธˆ ๋” ์ž์„ธํžˆ ๋‹ค๋ฃฐ ์˜ˆ์ •์ด๊ธฐ ๋•Œ๋ฌธ์— ์ง€๊ธˆ์€ ๊ทธ๋ƒฅ ์ด๋Ÿฐ ๊ฒƒ๋„ ์žˆ๊ตฌ๋‚˜... ๐Ÿค” ํ•˜๊ณ  ๋„˜์–ด๊ฐ€๋„ ์ข‹๋‹ค.
์•„๋ฌดํŠผ, ์ด๋ ‡๊ฒŒ ์„ ์–ธ์„ ํ•ด์ฃผ๊ฒŒ ๋˜๋ฉด, filterApples(inventory, Apple::isGreenApple)๊ณผ ๊ฐ™์€ ํ˜•์‹์œผ๋กœ ๋ฉ”์„œ๋“œ๋ฅผ ์ผ๊ธ‰ ๊ฐ์ฒด์ฒ˜๋Ÿผ ๋„˜๊ฒจ์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.



โœ”๏ธ ๋ฉ”์„œ๋“œ ๋ง๊ณ , ๋žŒ๋‹ค๋กœ ํ•ด๊ฒฐํ•ด๋ณผ๋ž˜?

๋ฉ”์„œ๋“œ๋กœ ์ „๋‹ฌํ•ด ์ฃผ๋ ค๋ฉด, ๊ฒฐ๊ตญ ๋ฉ”์„œ๋“œ๋ฅผ ์„ ์–ธํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ํ•˜์ง€๋งŒ, ๋ฉ”์„œ๋“œ๋ฅผ ์„ ์–ธํ•œ๋‹ค๋Š” ๊ฒƒ์€ ํ•ด๋‹น ๋ฉ”์„œ๋“œ์˜ ๋„ค์ด๋ฐ๊ณผ ์œ„์น˜๊นŒ์ง€ ๊ณ ๋ คํ•ด์•ผ ํ•˜๋Š” ๊ฒŒ ๋งŽ๋‹ค. ๊ท€์ฐฎ๋‹ค๋ฉด! ์ต๋ช…ํ•จ์ˆ˜ / ๋žŒ๋‹ค๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๋ฐ”๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ •์˜ํ•ด์ค„ ์ˆ˜๋„ ์žˆ๋‹ค.

filterApples(inventory, (Apple a) -> GREEN.equals(a.getColor());

์ด ๋ฉ”์„œ๋“œ ํ•˜๋‚˜ ์•ˆ์—์„œ "์‚ฌ๊ณผ์˜ ์ƒ‰์ƒ์ด ์ดˆ๋ก์ƒ‰์ธ ์‚ฌ๊ณผ๋ฅผ ํ•„ํ„ฐ๋งํ•œ๋‹ค"๊ฐ€ ๋ฐ”๋กœ ๋“œ๋Ÿฌ๋‚˜๋Š” ๊ฑธ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜, ๋ฌด๋ถ„๋ณ„ํ•˜๊ฒŒ ์‚ฌ์šฉํ•˜๋Š” ๊ฑด ์ข‹์ง€ ์•Š๋‹ค. ๋žŒ๋‹ค ๋‚ด๋ถ€์˜ ์‹์ด ๊ธธ์–ด์ง„๋‹ค๋ฉด ์˜คํžˆ๋ ค ๋ณด๊ธฐ ํž˜๋“ค๊ธฐ ๋•Œ๋ฌธ์— ๋ฉ”์„œ๋“œ๋กœ ์ •์˜ํ•ด์„œ ๋ฉ”์„œ๋“œ ๋„ค์ด๋ฐ์„ ํ†ตํ•ด ํ•ด๋‹น ๋ฉ”์„œ๋“œ๊ฐ€ ํ•˜๋Š” ์ผ์„ ์ž˜ ์ •์˜ํ•˜๊ณ , ๋ฉ”์„œ๋“œ ์ฐธ์กฐ๋ฅผ ์ง„ํ–‰ํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.


โœ”๏ธ  Stream ํ™œ์šฉํ•˜๊ธฐ

ํ•˜์ง€๋งŒ, ์œ„ ์ฝ”๋“œ์—์„œ๋„ ์—ฌ์ „ํžˆ ๋ถˆํŽธํ•œ ์ ์ด ์กด์žฌํ•œ๋‹ค.

List<Apple> result = new ArrayList<>();
        for (Apple apple: inventory) {
        if (p.test(apple)) { // p์— ๋Œ€ํ•œ ์กฐ๊ฑด ๊ฒ€์ฆ
        result.add(apple);
        }
        }

for-each๋ฅผ ํ†ตํ•ด ์ˆœํšŒ๋ฅผ ํ•˜๊ฒŒ ๋˜๋ฉด, ๋ช…์‹œ์ ์œผ๋กœ ๊ฒฐ๊ณผ๋ฅผ ๋„ฃ๊ธฐ ์œ„ํ•œ List ์„ ์–ธ๋ถ€ํ„ฐ ๋„ฃ์–ด์ฃผ๋Š” ๊ณผ์ •๊นŒ์ง€ ์ง์ ‘ ์„ ์–ธํ•ด์ค˜์•ผ ํ•œ๋‹ค. ํ•˜์ง€๋งŒ, ๊ฐœ๋ฐœ์ž๋Š” ๊ท€์ฐฎ๋‹ค. ์ปฌ๋ ‰์…˜์˜ for-each ๊ตฌ๋ฌธ์œผ๋กœ ํ†ตํ•ด ๊ฐ ์š”์†Œ๋ฅผ ๋ฐ˜๋ณตํ•˜๋ฉด์„œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋˜ (์™ธ๋ถ€ ๋ฐ˜๋ณต) ํ˜•์‹์—์„œ ๋ฒ—์–ด๋‚˜, ์ŠคํŠธ๋ฆผ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋‚ด๋ถ€์—์„œ ๋ชจ๋“  ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก (๋‚ด๋ถ€ ๋ฐ˜๋ณต) ์ง„ํ–‰ํ•ด๋ณด์ž.

// ์ˆœ์ฐจ ์ฒ˜๋ฆฌ
import static java.util.stream.Collectors.toList;
        List<Apple> heavyApples =
        inventory.stream()
        .filter((Apple a) -> a.getWeight() > 150)
        .collect(toList());

// ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ
        import static java.util.stream.Collectors.toList;
        List<Apple> heavyApples =
        inventory.parallelStream()
        .filter((Apple a) -> a.getWeight() > 150)
        .collect(toList());

์œ„์™€ ๊ฐ™์ด ์กฐ๊ฑด์„ ์ž‘์„ฑํ•˜๊ณ , collect()๋ฅผ ํ†ตํ•ด์„œ ํ•ด๋‹นํ•˜๋Š” ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ฐ”๋กœ ์–ป์–ด์˜ฌ ์ˆ˜ ์žˆ๋‹ค. ์ด์ œ, ๋ฆฌ์ŠคํŠธ๋ฅผ ์„ ์–ธํ•˜๊ณ  add๋ฅผ ํ†ตํ•ด ์ง์ ‘ ์ดˆ๊ณผํ•ด์ฃผ์—ˆ๋˜ ๊ณผ์ •์ด ์—†์–ด์ ธ์„œ ํ›จ์”ฌ ๊ฐ„๊ฒฐํ•ด์กŒ๋‹ค. ๋˜ํ•œ, ์ปฌ๋ ‰์…˜์—์„œ๋Š” ํฌ๊ธฐ๊ฐ€ ๋งค์šฐ ํฐ ๋ฆฌ์ŠคํŠธ์— ๋Œ€ํ•ด์„œ ๋‹จ์ˆœํžˆ for-each๋ฅผ ํ†ตํ•ด์„œ ์ฒ˜๋ฆฌํ•œ๋‹ค๋ฉด ์‹œ๊ฐ„์ด ๋” ๊ฑธ๋ฆด ํ…Œ์ง€๋งŒ, stream์˜ ๋ณ‘๋ ฌ์„ฑ์„ ์‚ฌ์šฉํ•˜๋ฉด ๋” ๋น ๋ฅด๊ฒŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์žฅ์ ์ด ์žˆ๋‹ค.

 

์—ฌ๊ธฐ์„œ, parallelStream์€ ์–ด๋–ป๊ฒŒ ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ๋ฅผ ์ง„ํ–‰ํ• ๊นŒ? ์ž๋ฐ”์—์„œ๋Š” ForkJoinPool ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๋ณ‘๋ ฌ์ฒ˜๋ฆฌ๋ฅผ ์ง„ํ–‰ํ•œ๋‹ค.

 

ForkJoinPool์€ ๋™์ผํ•œ ์ž‘์—…์„ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์„œ๋ธŒ ํƒœ์Šคํฌ๋กœ ๋ถ„๋ฆฌ(Fork)ํ•˜์—ฌ ์ฒ˜๋ฆฌํ•˜๊ณ , ์ด๋ฅผ ์ตœ์ข…์ ์œผ๋กœ ํ•ฉ์ณ์„œ(Join) ๊ฒฐ๊ณผ๋ฅผ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค. ์ŠคํŠธ๋ฆผ์—์„œ๋Š” ํ•˜๋‚˜๋Š” ์•ž๋ถ€๋ถ„์„, ํ•˜๋‚˜๋Š” ๋’ท๋ถ€๋ถ„์„ ์ฒ˜๋ฆฌํ•˜๊ณ  ๋งˆ์ง€๋ง‰์— ๋‘ ๊ฐœ๋ฅผ ํ•ฉ์ณ์„œ ๊ฒฐ๊ณผ๋ฅผ ๋‚ด๋ณด๋‚ด๋Š” ํ˜•์‹์ด๋‹ค. (๋‚ด๋ถ€์ ์œผ๋กœ Spliterator ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๋ถ„ํ• ์„ ์ง„ํ–‰ํ•œ๋‹ค)

 

๋˜ํ•œ, ์ŠคํŠธ๋ฆผ์„ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋ฉด ๊ฐ€๋ณ€ ๊ณต์œ  ๊ฐ์ฒด (=์ธ์Šคํ„ด์Šค ์ƒ์„ฑ ์ดํ›„์—, ๋‚ด๋ถ€ ์ƒํƒœ๊ฐ€ ๋ณ€๊ฒฝ ๊ฐ€๋Šฅํ•œ ๊ฐ์ฒด. List, Map... etc)์ด๋”๋ผ๋„ ์„œ๋กœ ๋…๋ฆฝ์ ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋ณ‘๋ ฌ์„ฑ์„ ์‰ฝ๊ฒŒ ๋ˆ„๋ฆด ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ด ํฐ ์žฅ์ ์ด๋‹ค.


โœ”๏ธ ๋””ํดํŠธ ๋ฉ”์„œ๋“œ์™€ ์ž๋ฐ” ๋ชจ๋“ˆ

์ด์ „์—๋Š” ์ธํ„ฐํŽ˜์ด์Šค(ex. List, Collection…)์— ๋Œ€ํ•ด์„œ stream.filter๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฌธ๋ฒ•์ด ์˜ค๋ฅ˜๊ฐ€ ๋‚ฌ์—ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜, ์ž๋ฐ”8์—์„œ๋Š” ๊ตฌํ˜„ ํด๋ž˜์Šค์—์„œ ๊ตฌํ˜„ํ•˜์ง€ ์•Š์•„๋„ ๋˜๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ์ธํ„ฐํŽ˜์ด์Šค์— ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•œ๋‹ค.

 

๋งŒ์•ฝ, ๊ธฐ์กด์— Collection ์ธํ„ฐํŽ˜์ด์Šค์— stream()์„ ์ถ”๊ฐ€ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด, ์ธํ„ฐํŽ˜์ด์Šค์ด๊ธฐ ๋•Œ๋ฌธ์— ํ•ด๋‹น ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋ชจ๋“  ๊ตฌํ˜„์ฒด๋“ค์— ๋Œ€ํ•ด์„œ stream() ๋ฉ”์„œ๋“œ๋ฅผ ๊ตฌํ˜„ํ–ˆ์–ด์•ผ ํ–ˆ๋‹ค. ์ฆ‰, ๊ตฌํ˜„ํ•˜๋Š” ํด๋ž˜์Šค๊ฐ€ ๋งŽ์•„์งˆ์ˆ˜๋ก ๋งค์šฐ๋งค์šฐ ๊ฐœ๋ฐœ์ž๋Š” ํž˜๋“ค์–ด์กŒ๋˜ ๊ฒƒ์ด๋‹ค ๐Ÿฅน (๋˜ํ•œ, 'OCP - ํ™•์žฅ์—๋Š” ์—ด๋ ค์žˆ์ง€๋งŒ ๋ณ€๊ฒฝ์—๋Š” ๋‹ซํ˜€์žˆ๋Š” ํ˜•ํƒœ'๋ฅผ ๋งŒ์กฑํ•˜์ง€ ์•Š๊ฒŒ ๋œ๋‹ค. ์ด๋Š” ํ™•์žฅ์„ฑ์ด ๋งค์šฐ ๋–จ์–ด์ง€๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.)

 

ํ•˜์ง€๋งŒ, ๋””ํดํŠธ ๋ฉ”์„œ๋“œ๊ฐ€ ๋‚˜์˜ค๋ฉด์„œ ์ธํ„ฐํŽ˜์ด์Šค์˜ ๋ณธ๋ฌธ(body)์— ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ถ”๊ฐ€ํ•˜์˜€์œผ๋ฉฐ, ๊ธฐ์กด์˜ ์ฝ”๋“œ๋ฅผ ๊ฑด๋“œ๋ฆฌ์ง€ ์•Š๊ณ ๋„ ์ž์œ ๋กญ๊ฒŒ ์„ค๊ณ„๋ฅผ ํ™•์žฅํ•  ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“ค์—ˆ๋‹ค. ๋˜ํ•œ, ๊ตฌํ˜„ ํด๋ž˜์Šค์—์„œ ์›ํ•œ๋‹ค๋ฉด ํ•ด๋‹น ํด๋ž˜์Šค๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“ค์–ด์„œ ๋”์šฑ ๋” ํ™•์žฅ์„ฑ์žˆ๋Š” ์„ค๊ณ„๋ฅผ ๊ฐ€๋Šฅํ•˜๋„๋ก ๋งŒ๋“ค์—ˆ๋‹ค.

 // List.java
default void sort(Comparator<? super E> c) {
        Object[] a = this.toArray();
        Arrays.sort(a, (Comparator) c);
        ListIterator<E> i = this.listIterator();
        for (Object e : a) {
        i.next();
        i.set((E) e);
        }
        }

์œ„ ์ฝ”๋“œ๋Š” List<T> ์ธํ„ฐํŽ˜์ด์Šค์˜ default ๋ฉ”์„œ๋“œ์ด๋‹ค. ์ด ๋•๋ถ„์— ์šฐ๋ฆฌ๋Š” ํ”ํžˆ ์ •๋ ฌ์„ ์ง„ํ–‰ํ•  ๋•Œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ๋‹ค.

List<Integer> list = new ArrayList<>();
        list.sort(Integer::compareTo);

๋˜ํ•œ, ArrayList ๋‚ด๋ถ€๋ฅผ ๋ณด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์˜ค๋ฒ„๋ผ์ด๋”ฉ์„ ํ†ตํ•ด sort()๋ฅผ ์žฌ๊ตฌํ˜„ํ•œ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

// ArrayList.java

@Override
@SuppressWarnings("unchecked")
public void sort(Comparator<? super E> c) {
final int expectedModCount = modCount;
        Arrays.sort((E[]) elementData, 0, size, c);
        if (modCount != expectedModCount)
        throw new ConcurrentModificationException();
        modCount++;
        }

 

 

๐Ÿ’ฌ ๊ทธ๋ ‡๋‹ค๋ฉด, ๋งŒ์•ฝ ํ•˜๋‚˜์˜ ํด๋ž˜์Šค๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ƒ์†๋ฐ›์•„์„œ, ํ•ด๋‹น ์ธํ„ฐํŽ˜์ด์Šค์— ์žˆ๋Š” ๋””ํดํŠธ ๋ฉ”์„œ๋“œ๋ฅผ ๋‘˜ ๋‹ค ๊ตฌํ˜„ํ•˜๊ฒŒ ๋˜๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ? ์ด๊ฒŒ ๊ณง ๋‹ค์ค‘ ์ƒ์†์„ ํ—ˆ์šฉํ•œ๋‹ค๋Š” ๊ฒƒ์ด ์•„๋‹๊นŒ?

// Grand.java
public interface Grand {
    void hello();
}

// Mom.java
public interface Mom extends Grand{
    @Override
    default void hello() {
        System.out.println("I'm your Mom.");
    }
}

// Dad.java
public interface Dad extends Grand{
    @Override
    default void hello() {
        System.out.println("I'm your Dad.");
    }
}

๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ƒํ™ฉ์ด ์žˆ์„ ๋•Œ, Mom๊ณผ Dad ๋ชจ๋‘๋ฅผ ์ƒ์†ํ•˜๋Š” ํด๋ž˜์Šค์ธ Child๊ฐ€ ์žˆ๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ?

class Child implements Mom, Dad{
}

๋‹ค์Œ๊ณผ ๊ฐ™์ด Mom๊ณผ Dad ๋ชจ๋‘์—์„œ ๋””ํดํŠธ ๋ฉ”์„œ๋“œ๊ฐ€ ์กด์žฌํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ์–ด๋–ค ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ• ์ง€ ์•Œ ์ˆ˜๊ฐ€ ์—†์–ด์„œ ์ปดํŒŒ์ผ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ , ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ '๋‹ค์ด์•„๋ชฌ๋“œ ์ƒ์† ๋ฌธ์ œ'๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค. 



โœ”๏ธ Optional<T> ํด๋ž˜์Šค

๋งˆ์ง€๋ง‰์œผ๋กœ, Optional์„ ํ†ตํ•ด ๊ฐ’์„ ๊ฐ–๊ฑฐ๋‚˜ ๊ฐ€์ง€์ง€ ์•Š์„ ์ˆ˜ ์žˆ๋Š” ๊ฐ์ฒด๋ฅผ ์ œ๊ณตํ•œ๋‹ค. ์ด๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด NPE๋ฅผ ํ”ผํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๊ฐ’์ด ์—†์„ ๋•Œ ์–ด๋–ค ์‹์œผ๋กœ ์ฒ˜๋ฆฌํ• ์ง€ ์™ธ๋ถ€์—์„œ ๊ฒฐ์ •ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ช…์‹œ์ ์œผ๋กœ ์ฒ˜๋ฆฌ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ์žฅ์ ์ด ์กด์žฌํ•œ๋‹ค.

 


์ฑ•ํ„ฐ 1์—์„œ๋Š” ์ž๋ฐ”8๋กœ ๋„˜์–ด์˜ค๋ฉด์„œ ๊ฐ„๋žตํ•˜๊ฒŒ ์–ด๋–ค ๊ธฐ๋Šฅ๋“ค์ด ์ถ”๊ฐ€๋˜์—ˆ๋Š”์ง€ ์•Œ์•„๋ดค๋‹ค.

์ถ”ํ›„ ์ฑ•ํ„ฐ๋ฅผ ์ง„ํ–‰ํ•˜๋ฉด์„œ ํ•ด๋‹น ๊ธฐ๋Šฅ๋“ค์— ๋Œ€ํ•ด ๋” ์ž์„ธํ•˜๊ฒŒ ๊ณต๋ถ€ํ•ด๋ณด์ž ๐Ÿ˜Ž

 

๐Ÿ’ก ์ •๋ฆฌ

- ์ž๋ฐ” 8์—์„œ๋Š” ๋ฉ”์„œ๋“œ๋ฅผ '์ผ๊ธ‰ ๊ฐ์ฒด'์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•œ๋‹ค. ๋žŒ๋‹ค์™€ ์ต๋ช… ํ•จ์ˆ˜๋ฅผ ํ™œ์šฉํ•˜์ž.
- ์ŠคํŠธ๋ฆผ์„ ํ†ตํ•ด์„œ ๋ฐ˜๋ณต๋˜๋Š” ์ฝ”๋“œ๋ฅผ ์ค„์ด๊ณ , ๋ณ‘๋ ฌ์„ฑ์„ ์‰ฝ๊ฒŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.
- ๋””ํดํŠธ ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ์ธํ„ฐํŽ˜์ด์Šค์— ๋Œ€ํ•œ ํ™•์žฅ์„ ์‰ฝ๊ฒŒ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ๋‹ค.
Comments