item 45 junghyunlyoo - JAVA-JIKIMI/EFFECTIVE-JAVA3 GitHub Wiki

์ŠคํŠธ๋ฆผ API์˜ ๋“ฑ์žฅ

์ŠคํŠธ๋ฆผ API๋Š” ๋‹ค๋Ÿ‰์˜ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ์ž‘์—…(์ˆœ์ฐจ์  ํ˜น์€ ๋ณ‘๋ ฌ์ )์„ ํšจ์œจ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•™ ์œ„ํ•ด ์ž๋ฐ” 8์— ์ถ”๊ฐ€๋˜์—ˆ๋‹ค.

์ŠคํŠธ๋ฆผ API์˜ ํ•ต์‹ฌ์€ ๋‘๊ฐ€์ง€๋‹ค.

1. ์ŠคํŠธ๋ฆผ(stream)์€ ๋ฐ์ดํ„ฐ ์›์†Œ์˜ ์œ ํ•œ ํ˜น์€ ๋ฌดํ•œ ์‹œํ€€์Šค๋ฅผ ๋œปํ•œ๋‹ค.

2. ์ŠคํŠธ๋ฆผ ํŒŒ์ดํ”„๋ผ์ธ(stream pipeline)์€ ์ด ์›์†Œ๋“ค๋กœ ์ˆ˜ํ–‰ํ•˜๋Š” ์—ฐ์‚ฐ ๋‹จ๊ณ„๋ฅผ ํ‘œํ˜„ํ•˜๋Š” ๊ฐœ๋…์ด๋‹ค.

์ŠคํŠธ๋ฆผ์˜ ์›์†Œ๋“ค์€ ์ปฌ๋ ‰์…˜, ๋ฐฐ์—ด, ํŒŒ์ผ, ์ •๊ทœํ‘œํ˜„์‹ ํŒจํ„ด ๋งค์ฒ˜, ๋‚œ์ˆ˜ ์ƒ์„ฑ๊ธฐ, ๋‹ค๋ฅธ ์ŠคํŠธ๋ฆผ ๋“ฑ ๋‹ค์–‘ํ•œ ๊ฒฝ๋กœ๋ฅผ ํ†ตํ•ด ์กด์žฌํ•  ์ˆ˜ ์žˆ๋‹ค.

์ŠคํŠธ๋ฆผ ์•ˆ์˜ ๋ฐ์ดํ„ฐ ์›์†Œ๋“ค์€ ๊ฐ์ฒด ์ฐธ์กฐ๋‚˜ ๊ธฐ๋ณธ ํƒ€์ž… ๊ฐ’์ด๋‹ค.

๊ธฐ๋ณธ ํƒ€์ž… ๊ฐ’์œผ๋กœ๋Š” int, long, double ์„ธ๊ฐ€์ง€๋ฅผ ์ง€์›ํ•œ๋‹ค.

IntStream intStream = IntStream.range(1, 5);
LongStream longStream = LongStream.range(1, 5);
DoubleStream doubleStream = DoubleStream.builder().add(1.2).build();

์ŠคํŠธ๋ฆผ ์—ฐ์‚ฐ

์ŠคํŠธ๋ฆผ ํŒŒ์ดํ”„๋ผ์ธ์€ ์†Œ์Šค ์ŠคํŠธ๋ฆผ์—์„œ ์‹œ์ž‘ํ•ด ์ข…๋‹จ ์—ฐ์‚ฐ์œผ๋กœ ๋๋‚œ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ๊ทธ ์‚ฌ์ด์— ํ•˜๋‚˜ ์ด์ƒ์˜ ์ค‘๊ฐ„ ์—ฐ์‚ฐ์ด ์žˆ์„ ์ˆ˜ ์žˆ๋‹ค.

๊ฐ ์ค‘๊ฐ„ ์—ฐ์‚ฐ์€ ํŠน์ • ๋ฐฉ์‹์œผ๋กœ ์ŠคํŠธ๋ฆผ์„ ๋ณ€ํ™˜ํ•œ๋‹ค.

์˜ˆ์ปจ๋Œ€ ๊ฐ ์›์†Œ์— ํ•จ์ˆ˜๋ฅผ ์ ์šฉํ•˜๊ฑฐ๋‚˜ ํŠน์ • ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜์ง€ ๋ชปํ•˜๋Š” ์›์†Œ๋ฅผ ๊ฑธ๋Ÿฌ๋‚ผ ์ˆ˜ ์žˆ๋‹ค.


์ค‘๊ฐ„ ์—ฐ์‚ฐ๋“ค์€ ๋ชจ๋‘ ํ•œ ์ŠคํŠธ๋ฆผ์„ ๋‹ค๋ฅธ ์ŠคํŠธ๋ฆผ์œผ๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค.

๋ณ€ํ™˜๋œ ์ŠคํŠธ๋ฆผ์˜ ์›์†Œ ํƒ€์ž…์€ ๋ณ€ํ™˜ ์ „ ์ŠคํŠธ๋ฆผ์˜ ์›์†Œ ํƒ€์ž…๊ณผ ๊ฐ™์„ ์ˆ˜๋„ ์žˆ๊ณ  ๋‹ค๋ฅผ ์ˆ˜๋„ ์žˆ๋‹ค.

์ข…๋‹จ ์—ฐ์‚ฐ์€ ๋งˆ์ง€๋ง‰ ์ค‘๊ฐ„ ์—ฐ์‚ฐ์ด ๋งŒ๋“  ์ŠคํŠธ๋ฆผ์— ๋งˆ์ง€๋ง‰ ์—ฐ์‚ฐ์„ ์ ์šฉํ•œ๋‹ค.

๋ณดํ†ต ์›์†Œ๋ฅผ ์ •๋ ฌํ•ด์„œ ์ปฌ๋ ‰์…˜์— ๋‹ด๊ฑฐ๋‚˜, ํŠน์ • ์›์†Œ๋ฅผ ์„ ํƒํ•˜๊ฑฐ๋‚˜, ๋ชจ๋“  ์›์†Œ๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค.

์ŠคํŠธ๋ฆผ ์ง€์—ฐํ‰๊ฐ€

์ŠคํŠธ๋ฆผ ํŒŒ์ดํ”„๋ผ์ธ์€ ์ง€์—ฐ ํ‰๊ฐ€(lazy evaluation)๋œ๋‹ค.

์ง€์—ฐ ํ‰๊ฐ€๋ฅผ '๊ฒŒ์œผ๋ฅธ ์—ฐ์‚ฐ' ์ด๋ผ๊ณ  ํ‘œํ˜„ํ•˜๊ธฐ๋„ ํ•œ๋‹ค.

ํ‰๊ฐ€(์ค‘๊ฐ„ ์—ฐ์‚ฐ)๋Š” ์ข…๋‹จ ์—ฐ์‚ฐ์ด ํ˜ธ์ถœ๋  ๋•Œ ์ด๋ค„์ง€๋ฉฐ ์ข…๋‹จ ์—ฐ์‚ฐ์— ์“ฐ์ด์ง€ ์•Š๋Š” ๋ฐ์ดํ„ฐ ์›์†Œ๋Š” ์‚ฌ์‹ค ์ค‘๊ฐ„ ์—ฐ์‚ฐ์„ ํฌํ•จํ•œ ๋ชจ๋“  ์—ฐ์‚ฐ์ด ์ ์šฉ๋˜์ง€ ์•Š๋Š”๋‹ค.

์ด๋Ÿฌํ•œ ์ง€์—ฐ ํ‰๊ฐ€๋Š” ๋ฌดํ•œ ์ŠคํŠธ๋ฆผ์„ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ์ค‘์š”ํ•œ ์š”์†Œ์ด๋‹ค.

์ข…๋‹จ ์—ฐ์‚ฐ์ด ์—†๋Š” ์ŠคํŠธ๋ฆผ ํŒŒ์ดํ”„๋ผ์ธ์€ ์•„๋ฌด ์ผ๋„ ํ•˜์ง€ ์•Š๋Š” ๋ช…๋ น์–ด์ธ no-op๊ณผ ๊ฐ™์œผ๋‹ˆ, ์ข…๋‹จ ์—ฐ์‚ฐ์„ ๋นผ๋จน๋Š” ์ผ์ด ์ ˆ๋Œ€๋กœ ์—†๋„๋ก ํ•ด์•ผ๊ฒ ๋‹ค.

Lazy Evaluation์ด๋ž€?

์ŠคํŠธ๋ฆผ API๋Š” ๋ฉ”์„œ๋“œ ์—ฐ์‡„๋ฅผ ์ง€์›ํ•˜๋Š” Fluent API

์ŠคํŠธ๋ฆผ API๋Š” ๋ฉ”์„œ๋“œ ์—ฐ์‡„๋ฅผ ์ง€์›ํ•˜๋Š” Fluent API๋‹ค.

์ฆ‰, ํŒŒ์ดํ”„๋ผ์ธ ํ•˜๋‚˜๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ํ˜ธ์ถœ๋“ค์„ ์—ฐ๊ฒฐํ•˜์—ฌ ๋‹จ ํ•˜๋‚˜์˜ ํ‘œํ˜„์‹์œผ๋กœ ์™„์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

ํŒŒ์ดํ”„๋ผ์ธ ์—ฌ๋Ÿฌ ๊ฐœ๋ฅผ ์—ฐ๊ฒฐํ•ด ํ‘œํ˜„์‹ ํ•˜๋‚˜๋กœ ๋งŒ๋“ค ์ˆ˜๋„ ์žˆ๋‹ค.


๊ธฐ๋ณธ์ ์œผ๋กœ ์ŠคํŠธ๋ฆผ ํŒŒ์ดํ”„๋ผ์ธ์€ ์ˆœ์ฐจ์ ์œผ๋กœ ์ˆ˜ํ–‰๋œ๋‹ค.

ํŒŒ์ดํ”„๋ผ์ธ์„ ๋ณ‘๋ ฌ๋กœ ์‹คํ–‰ํ•˜๋ ค๋ฉด ํŒŒ์ดํ”„๋ผ์ธ์„ ๊ตฌ์„ฑํ•˜๋Š” ์ŠคํŠธ๋ฆผ ์ค‘ ํ•˜๋‚˜์—์„œ parallel ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ด์ฃผ๊ธฐ๋งŒ ํ•˜๋ฉด ๋˜๋‚˜, ํšจ๊ณผ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ๋Š” ์ƒํ™ฉ์€ ๋งŽ์ง€ ์•Š๋‹ค. (item 48)

์ŠคํŠธ๋ฆผ API๋Š” ์ž˜์“ฐ๋ฉด ์•ฝ, ๋ชป์“ฐ๋ฉด ๋…!

์ŠคํŠธ๋ฆผ API๋Š” ๋‹ค์–‘ํ•œ ๊ณ„์‚ฐ์— ํ™œ์šฉ๋  ์ˆ˜ ์žˆ๋‹ค.

ํ•˜์ง€๋งŒ '์ž˜' ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค. ์ž˜๋ชป ์‚ฌ์šฉํ•˜๋ฉด ์ฝ๊ธฐ ์–ด๋ ต๊ณ  ์œ ์ง€๋ณด์ˆ˜๋„ ํž˜๋“ค์–ด์ง„๋‹ค.

์ŠคํŠธ๋ฆผ์„ ์–ธ์ œ ์จ์•ผ ํ•˜๋Š”์ง€๋ฅผ ๊ทœ์ •ํ•˜๋Š” ํ™•์‹คํ•œ ๊ทœ์น™์€ ์—†์ง€๋งŒ ์ฐธ๊ณ ํ•ด๋ณผ๋งŒํ•œ ๋…ธํ•˜์šฐ๋Š” ์žˆ๋‹ค.


์ŠคํŠธ๋ฆผ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์€ ์ฝ”๋“œ

๋‹ค์Œ ์ฝ”๋“œ๋ฅผ ๋ณด์ž. ์ด ํ”„๋กœ๊ทธ๋žจ์€ ์‚ฌ์ „ ํŒŒ์ผ์—์„œ ๋‹จ์–ด๋ฅผ ์ฝ์–ด ์‚ฌ์šฉ์ž๊ฐ€ ์ง€์ •ํ•œ ๋ฌธํ„ฑ๊ฐ’๋ณด๋‹ค ์›์†Œ ์ˆ˜๊ฐ€ ๋งŽ์€ ์•„๋‚˜๊ทธ๋žจ(anagram) ๊ทธ๋ฃน์„ ์ถœ๋ ฅํ•œ๋‹ค.

์•„๋‚˜๊ทธ๋žจ์ด๋ž€ ์ฒ ์ž๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ์•ŒํŒŒ๋ฒณ์ด ๊ฐ™๊ณ  ์ˆœ์„œ๋งŒ ๋‹ค๋ฅธ ๋‹จ์–ด๋ฅผ ๋œปํ•œ๋‹ค.

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

๋งต์˜ ํ‚ค๋Š” ๊ทธ ๋‹จ์–ด๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ์ฒ ์ž๋“ค์„ ์•ŒํŒŒ๋ฒณ์ˆœ์œผ๋กœ ์ •๋ ฌํ•œ ๊ฐ’์ด๋‹ค.

์ฆ‰ 'staple'์˜ ํ‚ค๋Š” 'aelpst'๊ฐ€ ๋˜๊ณ  'petals'์˜ ํ‚ค๋„ 'aelpst'๊ฐ€ ๋œ๋‹ค.

๋”ฐ๋ผ์„œ ๋‘ ๋‹จ์–ด๋Š” ์•„๋‚˜๊ทธ๋žจ์ด๊ณ  ์•„๋‚˜๊ทธ๋žจ๋ผ๋ฆฌ๋Š” ๊ฐ™์€ ํ‚ค๋ฅผ ๊ณต์œ ํ•œ๋‹ค.

๋งต์˜ ๊ฐ’์€ ๊ฐ™์€ ํ‚ค๋ฅผ ๊ณต์œ ํ•œ ๋‹จ์–ด๋“ค์„ ๋‹ด์€ ์ง‘ํ•ฉ์ด๋‹ค.

์‚ฌ์ „ ํ•˜๋‚˜๋ฅผ ๋ชจ๋‘ ์ฒ˜๋ฆฌํ•˜๊ณ  ๋‚˜๋ฉด ๊ฐ ์ง‘ํ•ฉ์€ ์‚ฌ์ „์— ๋“ฑ์žฌ๋œ ์•„๋‚˜๊ทธ๋žจ๋“ค์„ ๋ชจ๋‘ ๋‹ด์€ ์ƒํƒœ๊ฐ€ ๋œ๋‹ค.

๋งˆ์ง€๋ง‰์œผ๋กœ ์ด ํ”„๋กœ๊ทธ๋žจ์€ ๋งต์˜ values()๋กœ ์•„๋‚˜๊ทธ๋žจ ์ง‘ํ•ฉ๋“ค์„ ์–ป์–ด ์›์†Œ ์ˆ˜๊ฐ€ ๋ฌธํ„ฑ๊ฐ’๋ณด๋‹ค ๋งŽ์€ ์ง‘ํ•ฉ๋“ค์„ ์ถœ๋ ฅํ•œ๋‹ค.

public class IterativeAnagrams {
    public static void main(String[] args) throws IOException {
        File dictionary = new File(args[0]);
        int minGroupSize = Integer.parseInt(args[1]);

        Map<String, Set<String>> groups = new HashMap<>();
        try (Scanner s = new Scanner(dictionary)) {
            while (s.hasNext()) {
                String word = s.next();
                groups.computeIfAbsent(alphabetize(word),
                        (unused) -> new TreeSet<>()).add(word);
            }
        }

        for (Set<String> group : groups.values())
            if (group.size() >= minGroupSize)
                System.out.println(group.size() + ": " + group);
    }

    private static String alphabetize(String s) {
        char[] a = s.toCharArray();
        Arrays.sort(a);
        return new String(a);
    }
}

์ด ํ”„๋กœ๊ทธ๋žจ์˜ ์ฒซ ๋ฒˆ์งธ ๋‹จ๊ณ„์— ์ฃผ๋ชฉํ•˜์ž.

๋งต์— ๊ฐ ๋‹จ์–ด๋ฅผ ์‚ฝ์ž…ํ•  ๋•Œ ์ž๋ฐ” 8์—์„œ ์ถ”๊ฐ€๋œ computeIfAbsent()๋ฅผ ์‚ฌ์šฉํ–ˆ๋‹ค.

์ด ๋ฉ”์„œ๋“œ๋Š” ๋งต ์•ˆ์— ํ‚ค๊ฐ€ ์žˆ๋Š”์ง€ ์ฐพ์€ ๋‹ค์Œ, ์žˆ์œผ๋ฉด ๋‹จ์ˆœํžˆ ๊ทธ ํ‚ค์— ๋งคํ•‘๋œ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

ํ‚ค๊ฐ€ ์—†์œผ๋ฉด ๊ฑด๋„ค์ง„ ํ•จ์ˆ˜ ๊ฐ์ฒด๋ฅผ ํ‚ค์— ์ ์šฉํ•˜์—ฌ ๊ฐ’์„ ๊ณ„์‚ฐํ•ด๋‚ธ ๋‹ค์Œ ๊ทธ ํ‚ค์™€ ๊ฐ’์„ ๋งคํ•‘ํ•ด๋†“๊ณ , ๊ณ„์‚ฐ๋œ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

์ด์ฒ˜๋Ÿผ computeIfAbsent๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐ ํ‚ค์— ๋‹ค์ˆ˜์˜ ๊ฐ’์„ ๋งคํ•‘ํ•˜๋Š” ๋งต์„ ์‰ฝ๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.


์ŠคํŠธ๋ฆผ์„ ๊ณผํ•˜๊ฒŒ ์‚ฌ์šฉํ•œ ์ฝ”๋“œ

์ด์ œ ๋‹ค์Œ ํ”„๋กœ๊ทธ๋žจ์„ ์‚ดํŽด๋ณด์ž.

IterativeAnagrams์™€ ๊ฐ™์€ ์ผ์„ ํ•˜์ง€๋งŒ ์ŠคํŠธ๋ฆผ์„ ๊ณผํ•˜๊ฒŒ ํ™œ์šฉํ•œ๋‹ค.

์‚ฌ์ „ ํŒŒ์ผ์„ ์—ฌ๋Š” ๋ถ€๋ถ„๋งŒ ์ œ์™ธํ•˜๋ฉด ํ”„๋กœ๊ทธ๋žจ ์ „์ฒด๊ฐ€ ๋‹จ ํ•˜๋‚˜์˜ ํ‘œํ˜„์‹์œผ๋กœ ์ฒ˜๋ฆฌ๋œ๋‹ค.

์‚ฌ์ „์„ ์—ฌ๋Š” ์ž‘์—…์„ ๋ถ„๋ฆฌํ•œ ์ด์œ ๋Š” ๊ทธ์ € try-with-resources ๋ฌธ์„ ์‚ฌ์šฉํ•ด ์‚ฌ์ „ ํŒŒ์ผ์„ ์ œ๋Œ€๋กœ ๋‹ซ๊ธฐ ์œ„ํ•ด์„œ๋‹ค.

public class StreamAnagrams {
    public static void main(String[] args) throws IOException {
        Path dictionary = Paths.get(args[0]);
        int minGroupSize = Integer.parseInt(args[1]);

        try (Stream<String> words = Files.lines(dictionary)) {
            words.collect(
                    groupingBy(word -> word.chars().sorted()
                            .collect(StringBuilder::new,
                                    (sb, c) -> sb.append((char) c),
                                    StringBuilder::append).toString()))
                    .values().stream()
                    .filter(group -> group.size() >= minGroupSize)
                    .map(group -> group.size() + ": " + group)
                    .forEach(System.out::println);
        }
    }
}

์ดํ•ดํ•˜๊ธฐ ํž˜๋“  ์ฝ”๋“œ๋‹ค.... ์งง์ง€๋งŒ ์ฝ๊ธฐ ์–ด๋ ต๋‹ค. ํŠนํžˆ ์ŠคํŠธ๋ฆผ์— ์ต์ˆ™ํ•˜์ง€ ์•Š์€ ํ”„๋กœ๊ทธ๋ž˜๋จธ๋ผ๋ฉด ๋”์šฑ ๊ทธ๋ ‡๋‹ค.

์ด์ฒ˜๋Ÿผ ์ŠคํŠธ๋ฆผ์„ ๊ณผ์šฉํ•˜๋ฉด ํ”„๋กœ๊ทธ๋žจ ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ํž˜๋“ค์–ด์ง„๋‹ค.


์ŠคํŠธ๋ฆผ์„ ์ ๋‹นํžˆ ์‚ฌ์šฉํ•œ ์ฝ”๋“œ

๋‹คํ–‰ํžˆ ์ ˆ์ถฉ ์ง€์ ์ด ์žˆ๋‹ค. ์•„๋ž˜ ํ”„๋กœ๊ทธ๋žจ๋„ ์œ„ ๋‘ ํ”„๋กœ๊ทธ๋žจ๊ณผ ๊ธฐ๋Šฅ์€ ๊ฐ™๋‹ค.

ํ•˜์ง€๋งŒ ์ŠคํŠธ๋ฆผ์„ ์ ๋‹นํžˆ ์‚ฌ์šฉํ–ˆ๊ณ  ๊ทธ ๊ฒฐ๊ณผ ์ฝ”๋“œ์˜ ์–‘๊ณผ ๊ฐ€๋…์„ฑ ๋ชจ๋‘๋ฅผ ์–ป์—ˆ๋‹ค.

public class HybridAnagrams {
    public static void main(String[] args) throws IOException {
        Path dictionary = Paths.get(args[0]);
        int minGroupSize = Integer.parseInt(args[1]);

        try (Stream<String> words = Files.lines(dictionary)) {
            words.collect(groupingBy(word -> alphabetize(word)))
                    .values().stream()
                    .filter(group -> group.size() >= minGroupSize)
                    .forEach(g -> System.out.println(g.size() + ": " + g));
        }
    }

    private static String alphabetize(String s) {
        char[] a = s.toCharArray();
        Arrays.sort(a);
        return new String(a);
    }
}

try-with-resources์—์„œ ์‚ฌ์ „ ํŒŒ์ผ์„ ์—ด๊ณ , ํŒŒ์ผ์˜ ๋ชจ๋“  ๋ผ์ธ์œผ๋กœ ๊ตฌ์„ฑ๋œ ์ŠคํŠธ๋ฆผ์„ ์–ป๋Š”๋‹ค.

์ŠคํŠธ๋ฆผ ๋ณ€์ˆ˜์˜ ์ด๋ฆ„์„ words๋กœ ์ง€์–ด ์ŠคํŠธ๋ฆผ ์•ˆ์˜ ๊ฐ ์›์†Œ๊ฐ€ ๋‹จ์–ด(words)์ž„์„ ๋ช…ํ™•ํžˆ ํ–ˆ๋‹ค.

์ด ์ŠคํŠธ๋ฆผ์˜ ํŒŒ์ดํ”„๋ผ์ธ์—๋Š” ์ค‘๊ฐ„ ์—ฐ์‚ฐ์€ ์—†์œผ๋ฉฐ, ์ข…๋‹จ ์—ฐ์‚ฐ์—์„œ๋Š” ๋ชจ๋“  ๋‹จ์–ด๋ฅผ ์ˆ˜์ง‘ํ•ด ๋งต์œผ๋กœ ๋ชจ์€๋‹ค.

์ด ๋งต์€ ๋‹จ์–ด๋“ค์„ ์•„๋‚˜๊ทธ๋žจ๋ผ๋ฆฌ ๋ฌถ์–ด๋†“์€ ๊ฒƒ์ด๋‹ค. (item 46)

(์•ž์„  ๋‘ ํ”„๋กœ๊ทธ๋žจ์ด ์ƒ์„ฑํ•œ ๋งต๊ณผ ์‹ค์งˆ์ ์œผ๋กœ ๊ฐ™๋‹ค)

๊ทธ๋‹ค์Œ ์ด ๋งต์˜ values๊ฐ€ ๋ฐ˜ํ™˜ํ•œ ๊ฐ’์œผ๋กœ๋ถ€ํ„ฐ ์ƒˆ๋กœ์šด Stream<List> ์ŠคํŠธ๋ฆผ์„ ์—ฐ๋‹ค.

์ด ์ŠคํŠธ๋ฆผ์˜ ์›์†Œ๋Š” ๋ฌผ๋ก  ์•„๋‚˜๊ทธ๋žจ ๋ฆฌ์ŠคํŠธ๋‹ค.

๊ทธ ๋ฆฌ์ŠคํŠธ๋“ค ์ค‘ ์›์†Œ๊ฐ€ minGroupSize๋ณด๋‹ค ์ ์€ ๊ฒƒ์€ ํ•„ํ„ฐ๋ง๋ผ ๋ฌด์‹œ๋œ๋‹ค.

๋งˆ์ง€๋ง‰์œผ๋กœ ์ข…๋‹จ ์—ฐ์‚ฐ์ธ forEach๋Š” ์‚ด์•„๋‚จ์€ ๋ฆฌ์ŠคํŠธ๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค.

๋žŒ๋‹ค ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ์ด๋ฆ„์€ ์ฃผ์˜ํ•ด์„œ ์ •ํ•ด์•ผ ํ•œ๋‹ค.

HybridAnagrams์—์„œ์˜ ๋งค๊ฐœ๋ณ€์ˆ˜ g๋Š” ์‚ฌ์‹ค group์ด๋ผ๊ณ  ํ•˜๋Š”๊ฒŒ ์ข‹๋‹ค.

ํ•˜์ง€๋งŒ ์ฑ…์˜ ์ง€๋ฉด ํญ์ด ๋ถ€์กฑํ•ด ์งง๊ฒŒ ์ค„์˜€๋‹ค.

๋žŒ๋‹ค์—์„œ๋Š” ํƒ€์ž… ์ด๋ฆ„์„ ์ž์ฃผ ์ƒ๋žตํ•˜๋ฏ€๋กœ ๋งค๊ฐœ๋ณ€์ˆ˜ ์ด๋ฆ„์„ ์ž˜ ์ง€์–ด์•ผ ์ŠคํŠธ๋ฆผ ํŒŒ์ดํ”„๋ผ์ธ์˜ ๊ฐ€๋…์„ฑ์ด ์œ ์ง€๋œ๋‹ค.

ํ•œํŽธ, ๋‹จ์–ด์˜ ์ฒ ์ž๋ฅผ ์•ŒํŒŒ๋ฒณ์ˆœ์œผ๋กœ ์ •๋ ฌํ•˜๋Š” ์ผ์€ ๋ณ„๋„ ๋ฉ”์„œ๋“œ์ธ alphabetize์—์„œ ์ˆ˜ํ–‰ํ–ˆ๋‹ค. 

์—ฐ์‚ฐ์— ์ ์ ˆํ•œ ์ด๋ฆ„์„ ์ง€์–ด์ฃผ๊ณ  ์„ธ๋ถ€ ๊ตฌํ˜„์„ ์ฃผ ํ”„๋กœ๊ทธ๋žจ ๋กœ์ง ๋ฐ–์œผ๋กœ ๋นผ๋‚ด ์ „์ฒด์ ์ธ ๊ฐ€๋…์„ฑ์„ ๋†’์ธ ๊ฒƒ์ด๋‹ค. 

์ด์ฒ˜๋Ÿผ ๋„์šฐ๋ฏธ ๋ฉ”์„œ๋“œ๋ฅผ ์ ์ ˆํžˆ ํ™œ์šฉํ•˜๋Š” ์ผ์˜ ์ค‘์š”์„ฑ์€ ์ผ๋ฐ˜ ๋ฐ˜๋ณต ์ฝ”๋“œ์—์„œ๋ณด๋‹ค๋Š” ์ŠคํŠธ๋ฆผ ํŒŒ์ดํ”„๋ผ์ธ์—์„œ ํ›จ์”ฌ ํฌ๋‹ค.

์™œ๋ƒํ•˜๋ฉด ํŒŒ์ดํ”„๋ผ์ธ์—์„œ๋Š” ํƒ€์ž… ์ •๋ณด๊ฐ€ ๋ช…์‹œ๋˜์ง€ ์•Š๊ฑฐ๋‚˜ ์ž„์‹œ ๋ณ€์ˆ˜๋ฅผ ์ž์ฃผ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

alphabetize()๋„ ์ŠคํŠธ๋ฆผ์„ ์‚ฌ์šฉํ•ด ๋‹ค๋ฅด๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

ํ•˜์ง€๋งŒ ๋ช…ํ™•์„ฑ์ด ๋–จ์–ด์ง€๊ณ  ์ž˜๋ชป ๊ตฌํ˜„ํ•  ๊ฐ€๋Šฅ์„ฑ์ด ์ปค์งˆ ์ˆ˜๋„ ์žˆ๋‹ค. ์‹ฌ์ง€์–ด ๋А๋ ค์งˆ ์ˆ˜๋„ ์žˆ๋‹ค.

์ž๋ฐ”๊ฐ€ ๊ธฐ๋ณธ ํƒ€์ž…์ธ char์šฉ ์ŠคํŠธ๋ฆผ์„ ์ง€์›ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

์ž๋ฐ”๊ฐ€ char ์ŠคํŠธ๋ฆผ์„ ์ง€์›ํ–ˆ์–ด์•ผ ํ•œ๋‹ค๋Š” ๋œป์€ ์•„๋‹ˆ๋‹ค. ๊ทธ๋ ‡๊ฒŒ ํ•˜๋Š” ๊ฑด ๋ถˆ๊ฐ€๋Šฅํ–ˆ๋‹ค!

์•„๋ž˜๋Š” char ๊ฐ’๋“ค์„ ์ŠคํŠธ๋ฆผ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๋Š” ์ฝ”๋“œ๋‹ค.

"Hello world!".chars().forEach(System.out::print);

"Hello world!" ๋ฅผ ์ถœ๋ ฅํ•˜๋ฆฌ๋ผ ๊ธฐ๋Œ€ํ–ˆ๊ฒ ์ง€๋งŒ, 72101108~~~~~~033 ์„ ์ถœ๋ ฅํ•œ๋‹ค.

์™œ๋ƒํ•˜๋ฉด "Hello world!".chars()๊ฐ€ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ŠคํŠธ๋ฆผ์˜ ์›์†Œ๋Š” char๊ฐ€ ์•„๋‹Œ int์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

๋”ฐ๋ผ์„œ ์ •์ˆ˜๊ฐ’์„ ์ถœ๋ ฅํ•˜๋Š” print ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋œ ๊ฒƒ์ด๋‹ค.

์ด์ฒ˜๋Ÿผ ์ด๋ฆ„์ด chars์ธ๋ฐ int ์ŠคํŠธ๋ฆผ์„ ๋ฐ˜ํ™˜ํ•˜๋ฉด ํ—ท๊ฐˆ๋ฆด ์ˆ˜ ์žˆ๋‹ค.

์˜ฌ๋ฐ”๋ฅธ print ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๊ฒŒ ํ•˜๋ ค๋ฉด ๋‹ค์Œ์ฒ˜๋Ÿผ ํ˜•๋ณ€ํ™˜์„ ๋ช…์‹œ์ ์œผ๋กœ ํ•ด์•ผ ํ•œ๋‹ค.

"Hello world!".chars().forEach(x -> System.out::print((char) x));

char ๊ฐ’๋“ค์„ ์ฒ˜๋ฆฌํ•  ๋•Œ๋Š” ์ŠคํŠธ๋ฆผ์„ ์‚ผ๊ฐ€๋Š” ํŽธ์ด ๋‚ซ๊ฒ ๋‹ค

Stream์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์–ด๋ ค์šด ๊ฒฝ์šฐ

ํ•œํŽธ ์ŠคํŠธ๋ฆผ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์–ด๋ ค์šด ์ผ๋„ ์žˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, ํ•œ ๋ฐ์ดํ„ฐ๊ฐ€ ํŒŒ์ดํ”„๋ผ์ธ์˜ ์—ฌ๋Ÿฌ ๋‹จ๊ณ„(stage)๋ฅผ ํ†ต๊ณผํ•  ๋•Œ ์ด ๋ฐ์ดํ„ฐ์˜ ๊ฐ ๋‹จ๊ณ„์—์„œ์˜ ๊ฐ’๋“ค์— ๋™์‹œ์— ์ ‘๊ทผ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ๋ฅผ ๋“ค ์ˆ˜ ์žˆ๋‹ค.

์ŠคํŠธ๋ฆผ ํŒŒ์ดํ”„๋ผ์ธ์€ ์ผ๋‹จ ํ•œ ๊ฐ’์„ ๋‹ค๋ฅธ ๊ฐ’์— ๋งคํ•‘ํ•˜๊ณ  ๋‚˜๋ฉด ์›๋ž˜์˜ ๊ฐ’์„ ์žƒ์–ด๋ฒ„๋ฆฐ๋‹ค.

์›๋ž˜ ๊ฐ’๊ณผ ์ƒˆ๋กœ์šด ๊ฐ’์˜ ์Œ์„ ์ €์žฅํ•˜๋Š” ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•ด ๋งคํ•‘ํ•˜์—ฌ ์šฐํšŒํ•  ์ˆ˜๋„ ์žˆ์ง€๋งŒ ๊ทธ๋ฆฌ ์ข‹์€ ๋ฐฉ๋ฒ•์€ ์•„๋‹ˆ๋‹ค.

๋งคํ•‘ ๊ฐ์ฒด๊ฐ€ ํ•„์š”ํ•œ ๋‹จ๊ณ„๊ฐ€ ์—ฌ๋Ÿฌ ๊ณณ์ด๋ผ๋ฉด ํŠนํžˆ ๋” ๊ทธ๋ ‡๋‹ค

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

๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ๋ผ๋ฉด, ์•ž ๋‹จ๊ณ„์˜ ๊ฐ’์ด ํ•„์š”ํ•  ๋•Œ ๋งคํ•‘์„ ๊ฑฐ๊พธ๋กœ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ๋‚˜์„ ๊ฒƒ์ด๋‹ค.


'๋งคํ•‘์„ ๊ฑฐ๊พธ๋กœ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•'์„ ์˜ˆ๋ฅผ ๋“ค์–ด ๊ตฌ์ฒดํ™” ํ•ด๋ณด์ž.

์ฒ˜์Œ 20๊ฐœ์˜ ๋ฉ”๋ฅด์„ผ ์†Œ์ˆ˜๋ฅผ ์ถœ๋ ฅํ•˜๋Š” ํ”„๋กœ๊ทธ๋žจ์„ ์ž‘์„ฑํ•ด๋ณด์ž.

๋ฉ”๋ฅด์„ผ ์ˆ˜๋Š” 2^p - 1 ํ˜•ํƒœ์˜ ์ˆ˜๋‹ค.

์—ฌ๊ธฐ์„œ p๊ฐ€ ์†Œ์ˆ˜์ด๋ฉด ํ•ด๋‹น ๋ฉ”๋ฅด์„ผ ์ˆ˜๋„ ์†Œ์ˆ˜์ผ ์ˆ˜ ์žˆ๋Š”๋ฐ,

์ด๋•Œ์˜ ์ˆ˜๋ฅผ ๋ฉ”๋ฅด์„ผ ์†Œ์ˆ˜๋ผ ํ•œ๋‹ค.

์ด ํŒŒ์ดํ”„๋ผ์ธ์˜ ์ฒซ ์ŠคํŠธ๋ฆผ์œผ๋กœ๋Š” ๋ชจ๋“  ์†Œ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ๊ฒƒ์ด๋‹ค.

๋‹ค์Œ ์ฝ”๋“œ๋Š” (๋ฌดํ•œ) ์ŠคํŠธ๋ฆผ์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฉ”์„œ๋“œ๋‹ค.

static Stream<BigInteger> primes() {
    return Stream.iterate(TWO, BigInteger::nextProbablePrime);
}

๋ฉ”์„œ๋“œ ์ด๋ฆ„ primes๋Š” ์ŠคํŠธ๋ฆผ์˜ ์›์†Œ๊ฐ€ ์†Œ์ˆ˜์ž„์„ ๋งํ•ด์ค€๋‹ค.

์ŠคํŠธ๋ฆผ์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฉ”์„œ๋“œ ์ด๋ฆ„์€ ์ด์ฒ˜๋Ÿผ ์›์†Œ์˜ ์ •์ฒด๋ฅผ ์•Œ๋ ค์ฃผ๋Š” ๋ณต์ˆ˜ ๋ช…์‚ฌ๋กœ ์“ฐ๊ธฐ๋ฅผ ๊ฐ•๋ ฅํžˆ ์ถ”์ฒœํ•œ๋‹ค.

์ŠคํŠธ๋ฆผ ํŒŒ์ดํ”„๋ผ์ธ์˜ ๊ฐ€๋…์„ฑ์ด ํฌ๊ฒŒ ์ข‹์•„์ง„๋‹ค.

์ด ๋ฉ”์„œ๋“œ๊ฐ€ ์ด์šฉํ•˜๋Š” Stream.iterate๋ผ๋Š” ์ •์  ํŒฉํ„ฐ๋ฆฌ๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ 2๊ฐœ ๋ฐ›๋Š”๋‹ค.

์ฒซ ๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ์ŠคํŠธ๋ฆผ์˜ ์ฒซ ๋ฒˆ์งธ ์›์†Œ์ด๊ณ  ๋‘ ๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ์ŠคํŠธ๋ฆผ์—์„œ ๋‹ค์Œ ์›์†Œ๋ฅผ ์ƒ์„ฑํ•ด์ฃผ๋Š” ํ•จ์ˆ˜๋‹ค.

์ด์ œ ์ฒ˜์Œ 20๊ฐœ์˜ ๋ฉ”๋ฅด์„ผ ์†Œ์ˆ˜๋ฅผ ์ถœ๋ ฅํ•˜๋Š” ํ”„๋กœ๊ทธ๋žจ์„ ๋ณด์ž.

public static void main(String[] args) {
    primes().map(p -> TWO.pow(p.intValueExact()).subtract(ONE))
            .filter(mersenne -> mersenne.isProbablePrime(50))
            .limit(20)
            .forEach(System.out::println);
}

์ด ์ฝ”๋“œ๋Š” ์•ž์„œ์˜ ์„ค๋ช…์„ ์ •ํ™•ํ•˜๊ฒŒ ๊ตฌํ˜„ํ–ˆ๋‹ค.

์†Œ์ˆ˜๋“ค์„ ์‚ฌ์šฉํ•ด ๋ฉ”๋ฅด์„ผ ์ˆ˜๋ฅผ ๊ณ„์‚ฐํ•˜๊ณ , ๊ฒฐ๊ด๊ฐ’์ด ์†Œ์ˆ˜์ธ ๊ฒฝ์šฐ๋งŒ ๋‚จ๊ธด ๋‹ค์Œ (๋งค์ง๋„˜๋ฒ„ 50์€ ์†Œ์ˆ˜์„ฑ ๊ฒ€์‚ฌ๊ฐ€ true๋ฅผ ๋ฐ˜ํ™˜ํ•  ํ™•๋ฅ ์„ ์ œ์–ดํ•œ๋‹ค)

๊ฒฐ๊ณผ ์ŠคํŠธ๋ฆผ์˜ ์›์†Œ ์ˆ˜๋ฅผ 20๊ฐœ๋กœ ์ œํ•œํ•ด๋†“๊ณ  ์ž‘์—…์ด ๋๋‚˜๋ฉด ๊ฒฐ๊ณผ๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค.

์ด์ œ ์šฐ๋ฆฌ๊ฐ€ ๊ฐ ๋ฉ”๋ฅด์„ผ ์†Œ์ˆ˜์˜ ์•ž์— ์ง€์ˆ˜(p)๋ฅผ ์ถœ๋ ฅํ•˜๊ธธ ์›ํ•œ๋‹ค๊ณ  ํ•ด๋ณด์ž.

์ด ๊ฐ’์€ ์ดˆ๊ธฐ ์ŠคํŠธ๋ฆผ์—๋งŒ ๋‚˜ํƒ€๋‚˜๋ฏ€๋กœ ๊ฒฐ๊ณผ๋ฅผ ์ถœ๋ ฅํ•˜๋Š” ์ข…๋‹จ ์—ฐ์‚ฐ์—์„œ๋Š” ์ ‘๊ทผํ•  ์ˆ˜ ์—†๋‹ค.

ํ•˜์ง€๋งŒ ๋‹คํ–‰ํžˆ ์ฒซ ๋ฒˆ์งธ ์ค‘๊ฐ„ ์—ฐ์‚ฐ์—์„œ ์ˆ˜ํ–‰ํ•œ ๋งคํ•‘์„ ๊ฑฐ๊พธ๋กœ ์ˆ˜ํ–‰ํ•ด ๋ฉ”๋ฅด์„ผ ์ˆ˜์˜ ์ง€์ˆ˜๋ฅผ ์‰ฝ๊ฒŒ ๊ณ„์‚ฐํ•  ์ˆ˜ ์žˆ๋‹ค.

๋‹จ์ˆœํžˆ ์ˆซ์ž๋ฅผ ์ด์ง„์ˆ˜๋กœ ํ‘œํ˜„ํ•œ ๋‹ค์Œ ๋ช‡ ๋น„ํŠธ์ธ์ง€๋ฅผ ์„ธ๋ฉด ํ•ด๋‹น ์ˆซ์ž์˜ ์ง€์ˆ˜๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ, ์ข…๋‹จ ์—ฐ์‚ฐ์„ ๋‹ค์Œ์ฒ˜๋Ÿผ ์ž‘์„ฑํ•˜๋ฉด ๋œ๋‹ค.

.forEach(mp -> System.out.println(mp.bitLength() + ": " + mp));

Stream๊ณผ for-each ๋ชจ๋‘ ์ ์ ˆํ•œ ๊ฒฝ์šฐ

์ŠคํŠธ๋ฆผ๊ณผ ๋ฐ˜๋ณต ์ค‘ ์–ด๋А ์ชฝ์„ ์จ์•ผ ํ• ์ง€ ๋ฐ”๋กœ ์•Œ๊ธฐ ์–ด๋ ค์šด ์ž‘์—…๋„ ๋งŽ๋‹ค.

์นด๋“œ ๋ฑ์„ ์ดˆ๊ธฐํ™”ํ•˜๋Š” ์ž‘์—…์„ ์ƒ๊ฐํ•ด๋ณด์ž.

์นด๋“œ๋Š” ์ˆซ์ž(rank)์™€ ๋ฌด๋Šฌ(suit)๋ฅผ ๋ฌถ์€ ๋ถˆ๋ณ€ ๊ฐ’ ํด๋ž˜์Šค์ด๊ณ , ์ˆซ์ž์™€ ๋ฌด๋Šฌ๋Š” ๋ชจ๋‘ ์—ด๊ฑฐ ํƒ€์ž…์ด๋ผ ํ•˜์ž.

์ด ์ž‘์—…์€ ๋‘ ์ง‘ํ•ฉ์˜ ์›์†Œ๋“ค๋กœ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” ๊ฐ€๋Šฅํ•œ ๋ชจ๋“  ์กฐํ•ฉ์„ ๊ณ„์‚ฐํ•˜๋Š” ๋ฌธ์ œ๋‹ค.

์ˆ˜ํ•™์ž๋“ค์€ ์ด๋ฅผ ๋‘ ์ง‘ํ•ฉ์˜ ๋ฐ์นด๋ฅดํŠธ ๊ณฑ์ด๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค.

๋‹ค์Œ์€ for-each ๋ฐ˜๋ณต๋ฌธ์„ ์ค‘์ฒฉํ•ด์„œ ๊ตฌํ˜„ํ•œ ์ฝ”๋“œ๋กœ, ์ŠคํŠธ๋ฆผ์— ์ต์ˆ™ํ•˜์ง€ ์•Š์€ ์‚ฌ๋žŒ์—๊ฒŒ ์นœ์ˆ™ํ•œ ๋ฐฉ์‹์ด๋‹ค.

private static List<Card> newDeck() {
    List<Card> result = new ArrayList<>();
    for (Suit suit : Suit.values())
        for (Rank rank : Rank.values())
            result.add(new Card(suit, rank));
    return result;
}

๋‹ค์Œ์€ ์ŠคํŠธ๋ฆผ์œผ๋กœ ๊ตฌํ˜„ํ•œ ์ฝ”๋“œ๋‹ค.

์ค‘๊ฐ„ ์—ฐ์‚ฐ์œผ๋กœ ์‚ฌ์šฉํ•œ flatMap์€ ์ŠคํŠธ๋ฆผ์˜ ์›์†Œ ๊ฐ๊ฐ์„ ํ•˜๋‚˜์˜ ์ŠคํŠธ๋ฆผ์œผ๋กœ ๋งคํ•‘ํ•œ ๋‹ค์Œ ๊ทธ ์ŠคํŠธ๋ฆผ๋“ค์„ ๋‹ค์‹œ ํ•˜๋‚˜์˜ ์ŠคํŠธ๋ฆผ์œผ๋กœ ํ•ฉ์นœ๋‹ค.

์ด๋ฅผ ํ‰ํƒ„ํ™”(flattening)๋ผ๊ณ ๋„ ํ•œ๋‹ค. ์ด ๊ตฌํ˜„์—์„œ๋Š” ์ค‘์ฒฉ๋œ ๋žŒ๋‹ค๋ฅผ ์‚ฌ์šฉํ–ˆ์Œ์— ์ฃผ์˜ํ•˜์ž.

private static List<Card> newDeck() {
    return Stream.of(Suit.values())
            .flatMap(suit ->
                    Stream.of(Rank.values())
                            .map(rank -> new Card(suit, rank)))
            .collect(toList());
}

์–ด๋А ๋ฐฉ๋ฒ•์ด ์ข‹์„๊นŒ? ๊ฐœ์ธ ์ทจํ–ฅ๊ณผ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ํ™˜๊ฒฝ์˜ ๋ฌธ์ œ๋‹ค.

for-each๋ฅผ ์‚ฌ์šฉํ•œ ๋ฐฉ์‹์€ ๋” ๋‹จ์ˆœํ•˜๊ณ  ์ž์—ฐ์Šค๋Ÿฌ์›Œ ๋ณด์ธ๋‹ค.

์ŠคํŠธ๋ฆผ๊ณผ ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์— ์ต์ˆ™ํ•œ ํ”„๋กœ๊ทธ๋ž˜๋จธ๋ผ๋ฉด ์ŠคํŠธ๋ฆผ ๋ฐฉ์‹์ด ์กฐ๊ธˆ ๋” ๋ช…ํ™•ํ•˜๊ณ  ์‰ฌ์šธ ๊ฒƒ์ด๋‹ค.

(์–ด๋–ค ๋ฐฉ์‹์ด ๋งž์„ ์ง€ ๋ชจ๋ฅด๊ฒ ๋‹ค๋ฉด ์ฒซ ๋ฒˆ์งธ ๋ฐฉ์‹์„ ์“ฐ๋Š”๊ฒŒ ๋” ์•ˆ์ „ํ•  ๊ฒƒ์ด๋‹ค!)

โš ๏ธ **GitHub.com Fallback** โš ๏ธ