hades

[๋ชจ๋˜ ์ž๋ฐ” ์ธ ์•ก์…˜] ๋žŒ๋‹ค ํ‘œํ˜„์‹ ๋ณธ๋ฌธ

๐Ÿƒ๐Ÿปโ€โ™‚๏ธ ๊ธฐ๋ณธํ›ˆ๋ จ/Java

[๋ชจ๋˜ ์ž๋ฐ” ์ธ ์•ก์…˜] ๋žŒ๋‹ค ํ‘œํ˜„์‹

hades1 2024. 9. 4. 09:56

ํ•„์š”์„ฑ

์ต๋ช… ํด๋ž˜์Šค๋กœ ๋‹ค์–‘ํ•œ ๋™์ž‘์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ๋งŒ์กฑํ•  ๋งŒํผ ์ฝ”๋“œ๊ฐ€ ๊น”๋”ํ•˜์ง€๋Š” ์•Š์•˜๋‹ค. ๋žŒ๋‹ค ํ‘œํ˜„์‹์€ ์ต๋ช… ํด๋ž˜์Šค์ฒ˜๋Ÿผ ์ด๋ฆ„์ด ์—†๋Š” ํ•จ์ˆ˜์ด๋ฉด์„œ ๋ฉ”์†Œ๋“œ๋ฅผ ์ธ์ˆ˜๋กœ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๋žŒ๋‹ค ํ‘œํ˜„์‹์ด ์ต๋ช… ํด๋ž˜์Šค๋ฅผ ๋Œ€์‹ ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

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

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

  • ์ต๋ช… : ๋ณดํ†ต์˜ ๋ฉ”์†Œ๋“œ์™€๋Š” ๋‹ฌ๋ฆฌ ์ด๋ฆ„์ด ์—†์œผ๋ฏ€๋กœ ์ต๋ช…์ด๋ผ๊ณ  ํ‘œํ˜„ํ•œ๋‹ค.
  • ํ•จ์ˆ˜ : ๋žŒ๋‹ค๋Š” ๋ฉ”์†Œ๋“œ์™€๋Š” ๋‹ฌ๋ฆฌ ํŠน์ • ํด๋ž˜์Šค์— ์ข…์†๋˜์ง€ ์•Š์œผ๋ฏ€๋กœ ํ•จ์ˆ˜๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค. ํ•˜์ง€๋งŒ, ๋ฉ”์†Œ๋“œ์ฒ˜๋Ÿผ ํŒŒ๋ผ๋ฏธํ„ฐ ๋ฆฌ์ŠคํŠธ, ๋ฐ”๋””, ๋ฐ˜ํ™˜ ํ˜•์‹, ๊ฐ€๋Šฅํ•œ ์˜ˆ์™ธ ๋ฆฌ์ŠคํŠธ๋ฅผ ํฌํ•จํ•œ๋‹ค.
  • ์ „๋‹ฌ : ๋žŒ๋‹ค ํ‘œํ˜„์‹์„ ๋ฉ”์†Œ๋“œ ์ธ์ˆ˜๋กœ ์ „๋‹ฌํ•˜๊ฑฐ๋‚˜ ๋ณ€์ˆ˜๋กœ ์ €์žฅํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ๊ฐ„๊ฒฐ์„ฑ : ์ต๋ช… ํด๋ž˜์Šค์™€๋Š” ๋‹ฌ๋ฆฌ ๋งŽ์€ ์ž์งˆ๊ตฌ๋ ˆํ•œ ์ฝ”๋“œ๋ฅผ ๊ตฌํ˜„ํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค.

 

๋žŒ๋‹ค๋Š” ํ™”์‚ดํ‘œ ์ขŒ์ธก์˜ ํŒŒ๋ผ๋ฏธํ„ฐ, ํ™”์‚ดํ‘œ, ํ™”์‚ดํ‘œ ์šฐ์ธก์˜ ๋ฐ”๋””๋กœ ์ด๋ฃจ์–ด์ง„๋‹ค. ๋žŒ๋‹ค ํ‘œํ˜„์‹์—๋Š” return์ด ํ•จ์ถ•๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ return์„ ๋ช…์‹œํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค. ๋˜ํ•œ ์—ฌ๋Ÿฌ ํ–‰์˜ ๋ฌธ์žฅ์„ ํฌํ•จํ•  ์ˆ˜ ์žˆ๋‹ค.

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

 

๋Ÿ„๋Œœ ํ‘œํ˜„์‹์˜ ๋ฌธ๋ฒ•์—๋Š” ๋‘ ๊ฐ€์ง€ ์Šคํƒ€์ผ์ด ์žˆ๋‹ค.

  • ํ‘œํ˜„์‹ ์Šคํƒ€์ผ : (parameter) -> expression
  • ๋ธ”๋ก ์Šคํƒ€์ผ : (parameter) -> { statement1; statement2; }

์ฃผ์˜ํ•ด์•ผ ํ•  ๊ฒƒ์€ ํ‘œํ˜„์‹ ์Šคํƒ€์ผ์—๋Š” return์ด ํ•จ์ถ•๋˜์–ด ์žˆ์ง€๋งŒ, ๋ธ”๋ก ์Šคํƒ€์ผ์—์„œ๋Š” ํ•จ์ถ•๋˜์–ด ์žˆ์ง€ ์•Š๋‹ค. ๋”ฐ๋ผ์„œ, ํ•„์š”ํ•œ ๊ฒฝ์šฐ์—๋Š” ๋ช…์‹œ์ ์œผ๋กœ return ๋ฌธ์„ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.

 

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

ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค

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

 

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

 

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

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

 

cf) ์‹œ๊ทธ๋‹ˆ์ฒ˜๋ž€ ๋ฉ”์†Œ๋“œ ๋ช…๊ณผ ํŒŒ๋ผ๋ฏธํ„ฐ ํƒ€์ž…, ๊ฐœ์ˆ˜๋ฅผ ์˜๋ฏธํ•œ๋‹ค. ์ปดํŒŒ์ผ์„ ํ•  ๋•Œ, ๋ฉ”์†Œ๋“œ ์‹œ๊ทธ๋‹ˆ์ฒ˜๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๋ฉ”์†Œ๋“œ๋ฅผ ๋ถ„๋ฅ˜ํ•œ๋‹ค. 

 

@FunctionalInterface

ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ์–ด๋…ธํ…Œ์ด์…˜์ด๋‹ค. ์ด ์–ด๋…ธํ…Œ์ด์…˜์œผ๋กœ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์„ ์–ธํ–ˆ์ง€๋งŒ, ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค, ์ฆ‰ ํ•˜๋‚˜์˜ ์ถ”์ƒ ๋ฉ”์†Œ๋“œ๋งŒ ๊ฐ€์ง€๊ณ  ์žˆ์ง€ ์•Š๋‹ค๋ฉด, ์ปดํŒŒ์ผ ์—๋Ÿฌ๋ฅผ ๋ฐœ์ƒ์‹œํ‚จ๋‹ค.

 

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

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ํŒŒ์ผ ์ฒ˜๋ฆฌ ๊ฐ™์€ ์ž์›์„ ์ฒ˜๋ฆฌํ•  ๋•Œ, ์ž์›์„ ์—ด๊ณ (์„ค์ •), ์ฒ˜๋ฆฌ, ์ž์›์„ ๋‹ซ๋Š”(์ •๋ฆฌ) ์ˆœ์„œ๋กœ ์ด๋ฃจ์–ด์ง„๋‹ค. ์ด ์ˆœ์„œ๋กœ ์ด๋ฃจ์–ด์ง„ ์ฝ”๋“œ๋“ค์„ ์‹คํ–‰ ์–ด๋ผ์šด๋“œ ํŒจํ„ด์ด๋ผ๊ณ  ํ•œ๋‹ค.

 

์•„๋ž˜ ์ฝ”๋“œ๋Š” ํŒŒ์ผ์„ ์—ด๊ณ , ํ•œ ์ค„์„ ๋ฐ˜ํ™˜ํ•˜๊ณ , ๋‹ซ๋Š” ์ฝ”๋“œ์ด๋‹ค.

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

 

ํ•˜์ง€๋งŒ, ๋™์ž‘์„ ๋‹ค๋ฅด๊ฒŒ ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด, ํŒŒ์ผ์„ ์—ด๊ณ  ๋‹ซ๋Š” ๊ฒƒ์€ ์œ ์ง€ํ•œ ์ฑ„๋กœ ์ฒ˜๋ฆฌ ๋ถ€๋ถ„์„ ๋ฐ”๊ฟ”์•ผ ํ•œ๋‹ค.

@FunctionalInterface
public interface BufferedReaderProcessor {
    public String process(BufferedReader br) throws IOException;
}
public String processFile(BufferedReaderProcessor brp) throws IOException {
    try (BufferedReader br = new BufferedReader(new FileReader("data.txt"))) {
        return brp.process(br);
    }
}
String oneLine = processFile((BufferedReader br) -> br.readLine());
String twoLine = processFile((BufferedReader br) -> br.readLine() + br.readLine());

 

ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค ์‚ฌ์šฉ

ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค์˜ ์ถ”์ƒ ๋ฉ”์†Œ๋“œ๋Š” ๋žŒ๋‹ค ํ‘œํ˜„์‹์˜ ์‹œ๊ทธ๋‹ˆ์ฒ˜๋ฅผ ๋ฌ˜์‚ฌํ•˜๊ณ , ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค์˜ ์ถ”์ƒ ๋ฉ”์†Œ๋“œ ์‹œ๊ทธ๋‹ˆ์ฒ˜๋ฅผ ํ•จ์ˆ˜ ๋””์Šคํฌ๋ฆฝํ„ฐ๋ผ๊ณ  ํ•œ๋‹ค. ๋‹ค์–‘ํ•œ ๋žŒ๋‹ค ํ‘œํ˜„์‹์„ ์‚ฌ์šฉํ•˜๋ ค๋ฉด, ๋‹ค์–‘ํ•œ ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ํ•„์š”ํ•˜๋‹ค.

 

์ž๋ฐ”์—์„œ๋Š” ๋งŽ์€ ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํฌํ•จํ•˜๊ณ  ์žˆ์œผ๋ฉฐ, ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

 

Predicate

Predicate<T> ์ธํ„ฐํŽ˜์ด์Šค๋Š” test๋ผ๋Š” ์ถ”์ƒ ๋ฉ”์†Œ๋“œ๋ฅผ ์ •์˜ํ•˜๋ฉฐ, test๋Š” T ํ˜•์‹์˜ ๊ฐ์ฒด๋ฅผ ์ธ์ˆ˜๋กœ ๋ฐ›์•„ ๋ถˆ๋ฆฌ์–ธ์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ์ฐธ ๋˜๋Š” ๊ฑฐ์ง“์ด๋ผ๋Š” ๋ช…์ œ(predicate)์˜ ๊ฒฐ๊ณผ๋ฅผ ์–ป๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•œ๋‹ค.

public <T> List<T> filter(List<T> list, Predicate<T> p){
    List<T> result = new ArrayList<>();
    for (T t : list){
        if (p.test(t)){
            result.add(t);
        }
    }
    return result;
}
List<String> nonEmptyList = filter(Arrays.asList("๋ชจ๋˜", "์ž๋ฐ”", "์ธ", "์•ก์…˜"), (String s) -> !s.isEmpty());

 

Consumer

Consumer<T> ์ธํ„ฐํŽ˜์ด์Šค๋Š” accept๋ผ๋Š” ์ถ”์ƒ ๋ฉ”์†Œ๋“œ๋ฅผ ์ •์˜ํ•˜๋ฉฐ, accpet๋Š” T ํ˜•์‹์˜ ๊ฐ์ฒด๋ฅผ ์ธ์ˆ˜๋กœ ๋ฐ›์•„ void๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ๋ฐ˜ํ™˜๊ฐ’ ํ•„์š”์—†์ด ๋‹จ์ง€ ์†Œ๋น„(consume)ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•œ๋‹ค.

public <T> void forEach(List<T> list, Consumer<T> c){
    for (T t : list){
        c.accept(t);
    }
}
forEach(Arrays.asList("๋ชจ๋˜", "์ž๋ฐ”", "์ธ", "์•ก์…˜"), (String s) -> System.out.println());

 

Function

Function<T, R> ์ธํ„ฐํŽ˜์ด์Šค๋Š” apply๋ผ๋Š” ๋ฉ”์†Œ๋“œ๋ฅผ ์ •์˜ํ•˜๋ฉฐ, ์ œ๋„ˆ๋ฆญ ํ˜•์‹ T๋ฅผ ์ธ์ˆ˜๋กœ ๋ฐ›์•„์„œ ์ œ๋„ˆ๋ฆญ ํ˜•์‹ R ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

public <T, R> List<R> map(List<T> list, Function<T, R> f){
    List<R> result = new ArrayList<>();
    for (T t : list){
        result.add(f.apply(t));
    }
    return result;
}
List<Integer> l = map(Arrays.asList("๋ชจ๋˜", "์ž๋ฐ”", "์ธ", "์•ก์…˜"), (String s) -> s.length());

 

๊ธฐ๋ณธํ˜• ํŠนํ™”

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

 

๊ทธ๋ž˜์„œ ๋“ฑ์žฅํ•œ ๊ฒƒ์ด IntPredicate, IntConsumer ๊ฐ™์€ ๊ธฐ๋ณธํ˜• ํŠนํ™” ์ธํ„ฐํŽ˜์ด์Šค์ด๋‹ค. ์ด ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด, ๋ฐ•์‹ฑ, ์–ธ๋ฐ•์‹ฑ์ด ์ผ์–ด๋‚˜์ง€ ์•Š๋Š”๋‹ค.

IntPredicate evenNumbers = (int i) -> i % 2 != 0;
Predicate<Integer> oddNumbers = (Integer i) -> i % 2 != 0;	// ๋ฐ•์‹ฑ, ์–ธ๋ฐ•์‹ฑ ๋ฐœ์ƒ

 

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

ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๋Š” ํ™•์ธ๋œ ์˜ˆ์™ธ๋ฅผ ๋˜์ง€๋Š” ๋™์ž‘์„ ํ—ˆ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค. ์ฆ‰, ์˜ˆ์™ธ๋ฅผ ๋˜์ง€๋Š” ๋žŒ๋‹ค ํ‘œํ˜„์‹์„ ๋งŒ๋“ค๋ ค๋ฉด ํ™•์ธ๋œ ์˜ˆ์™ธ๋ฅผ ์„ ์–ธํ•˜๋Š” ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ง์ ‘ ์ •์˜ํ•˜๊ฑฐ๋‚˜ ๋žŒ๋‹ค๋ฅผ try-catch ๋ธ”๋ก์œผ๋กœ ๊ฐ์‹ธ์•ผ ํ•œ๋‹ค. ๋ณดํ†ต์€ ํ›„์ž๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

 

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

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

 

ํ˜•์‹ ๊ฒ€์‚ฌ

๋žŒ๋‹ค๊ฐ€ ์‚ฌ์šฉ๋˜๋Š” ์ฝ˜ํ…์ŠคํŠธ๋ฅผ ์ด์šฉํ•ด์„œ ๋žŒ๋‹ค์˜ ํ˜•์‹์„ ์ถ”๋ก ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ฝ˜ํ…์ŠคํŠธ๋ž€ ๋žŒ๋‹ค๊ฐ€ ์ „๋‹ฌ๋  ๋ฉ”์†Œ๋“œ ํŒŒ๋ผ๋ฏธํ„ฐ๋‚˜ ๋žŒ๋‹ค๊ฐ€ ํ• ๋‹น๋˜๋Š” ๋ณ€์ˆ˜ ๋“ฑ์„ ๋งํ•œ๋‹ค. ๊ทธ ์ฝ˜ํ…์ŠคํŠธ์—์„œ ๊ธฐ๋Œ€๋˜๋Š” ๋žŒ๋‹ค ํ‘œํ˜„์‹์˜ ํ˜•์‹์„ ๋Œ€์ƒ ํ˜•์‹์ด๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค.

 

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

๋Œ€์ƒ ํ˜•์‹์ด๋ผ๋Š” ํŠน์ง• ๋•Œ๋ฌธ์— ๊ฐ™์€ ๋žŒ๋‹ค ํ‘œํ˜„์‹์ด๋”๋ผ๋„ ํ˜ธํ™˜๋˜๋Š” ์ถ”์ƒ ๋ฉ”์†Œ๋“œ๋ฅผ ๊ฐ€์ง„ ๋‹ค๋ฅธ ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๋กœ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, Callable๊ณผ PriviledgedAction ์ธํ„ฐํŽ˜์ด์Šค ๋ชจ๋‘ ์ธ์ˆ˜๋ฅผ ๋ฐ›์ง€ ์•Š๊ณ , ์ œ๋„ˆ๋ฆญ ํ˜•์‹ T๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ถ”์ƒ ๋ฉ”์†Œ๋“œ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.

 

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

๋žŒ๋‹ค์˜ ๋ฐ”๋””์— ์ผ๋ฐ˜ ํ‘œํ˜„์‹์ด ์žˆ์œผ๋ฉด, void๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜ ๋””์Šคํฌ๋ฆฝํ„ฐ์™€ ํ˜ธํ™˜๋œ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ํ‘œํ˜„์‹์ด void๊ฐ€ ์•„๋‹Œ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜์—ฌ๋„ void๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค์˜ ์ถ”์ƒ ๋ฉ”์†Œ๋“œ์™€ ํ˜ธํ™˜๋œ๋‹ค.

 

ํ˜•์‹ ์ถ”๋ก 

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

 

Comparator<T>๋ฅผ ์‚ดํŽด๋ณด๋ฉด, ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

int compare(T o1, T o2);
Comparator<Apple> c = (Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight());
Comparator<Apple> c =  (a1, a2) -> a1.getWeight().compareTo(a2.getWeight());

 

์ƒํ™ฉ์— ๋”ฐ๋ผ ๋ช…์‹œ์ ์œผ๋กœ ํ˜•์‹์„ ํฌํ•จํ•˜๋Š” ๊ฒƒ์ด ์ข‹์„ ๋•Œ๋„ ์žˆ๊ณ , ํ˜•์‹์„ ๋ฐฐ์ œํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€๋…์„ฑ์„ ํ–ฅ์ƒ์‹œํ‚ฌ ๋•Œ๋„ ์žˆ๋‹ค. ์–ด๋–ค ๋ฐฉ๋ฒ•์ด ์ข‹์€์ง€๋Š” ๊ฒฐ์ •ํ•˜๊ธฐ ๋‚˜๋ฆ„์ด๋‹ค.

 

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

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

 

๋žŒ๋‹ค์—์„œ ์ง€์—ญ ๋ณ€์ˆ˜์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฐ€์ • ํ•˜์—, ๋žŒ๋‹ค๊ฐ€ ์Šค๋ ˆ๋“œ์—์„œ ์‹คํ–‰๋œ๋‹ค๋ฉด ๋ณ€์ˆ˜๋ฅผ ํ• ๋‹นํ•œ ์Šค๋ ˆ๋“œ๊ฐ€ ์‚ฌ๋ผ์ ธ์„œ ๋ณ€์ˆ˜ ํ• ๋‹น์ด ํ•ด์ œ๋˜์—ˆ์„ ๋•Œ ๋žŒ๋‹ค๋ฅผ ์‹คํ–‰ํ•˜๋Š” ์Šค๋ ˆ๋“œ์—์„œ๋Š” ํ•ด๋‹น ๋ณ€์ˆ˜์— ์ ‘๊ทผํ•˜๋ ค ํ•  ์ˆ˜ ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ž๋ฐ” ๊ตฌํ˜„์—์„œ๋Š” ์›๋ž˜ ๋ณ€์ˆ˜๊ฐ€ ์•„๋‹ˆ๋ผ ์ง€์—ญ ๋ณ€์ˆ˜์˜ ๋ณต์‚ฌ๋ณธ์„ ์ œ๊ณตํ•œ๋‹ค.

 

๋ฉ”์†Œ๋“œ ์ฐธ์กฐ

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

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

inventory.sort(Comparator.comparing(Apple::getWeight));

๋ฉ”์†Œ๋“œ ์ฐธ์กฐ๋Š” ํด๋ž˜์Šค::๋ฉ”์†Œ๋“œ๋ช…์˜ ํ˜•ํƒœ๋กœ ์ด๋ฃจ์–ด์ง€๋ฉฐ, ํŠน์ • ๋ฉ”์†Œ๋“œ๋งŒ์„ ํ˜ธ์ถœํ•˜๋Š” ๋žŒ๋‹ค์˜ ์ถ•์•ฝํ˜•์ด๋ผ๊ณ  ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ๋‹ค. ์‹ค์ œ๋กœ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋ฏ€๋กœ ๊ด„ํ˜ธ๋Š” ํ•„์š”์—†๋‹ค.

 

๋ฉ”์†Œ๋“œ ์ฐธ์กฐ๋ฅผ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์ด ์•„๋‹ˆ๋ผ ํ•˜๋‚˜์˜ ๋ฉ”์†Œ๋“œ๋ฅผ ์ฐธ์กฐํ•˜๋Š” ๋žŒ๋‹ค๋ฅผ ํŽธ๋ฆฌํ•˜๊ฒŒ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฌธ๋ฒ•์œผ๋กœ ๊ฐ„์ฃผํ•  ์ˆ˜ ์žˆ๋‹ค.

 

๋ฉ”์†Œ๋“œ ์ฐธ์กฐ๋ฅผ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•

  1. ์ •์  ๋ฉ”์†Œ๋“œ ์ฐธ์กฐ : ์˜ˆ๋ฅผ ๋“ค์–ด Integer์˜ parseInt ๋ฉ”์†Œ๋“œ๋Š” Integer::parseInt๋กœ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.
  2. ๋‹ค์–‘ํ•œ ํ˜•์‹์˜ ์ธ์Šคํ„ด์Šค ๋ฉ”์†Œ๋“œ ์ฐธ์กฐ : ์˜ˆ๋ฅผ ๋“ค์–ด String์˜ length ๋ฉ”์†Œ๋“œ๋Š” String::length๋กœ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.
  3. ๊ธฐ์กด ๊ฐ์ฒด์˜ ์ธ์Šคํ„ด์Šค ๋ฉ”์†Œ๋“œ ์ฐธ์กฐ : ์˜ˆ๋ฅผ ๋“ค์–ด Transaction ๊ฐ์ฒด๋ฅผ ํ• ๋‹น๋ฐ›์€ expensiveTransaction ์ง€์—ญ ๋ณ€์ˆ˜๊ฐ€ ์žˆ๊ณ , Transaction ๊ฐ์ฒด์— getValue ๋ฉ”์†Œ๋“œ๊ฐ€ ์žˆ๋‹ค๋ฉด, expensiveTransaction::getValue๋กœ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

List<String> str = Arrays.asList("a", "b", "A", "B");
str.sort((s1, s2) -> s1.compareToIgnoreCase(s2));

List<String> str = Arrays.asList("a", "b", "A", "B");
str.sort(String::compareToIgnoreCase);
Function<String, Integer> stringToInteger = Integer::parseInt;
Integer apply = stringToInteger.apply("1234");
private boolean startsWithNumber(String string){
    return Character.isDigit(string.charAt(0));
}

Predicate<String> startsWithNumber = this::startsWithNumber;

 

์ƒ์„ฑ์ž ์ฐธ์กฐ

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

Supplier<Apple> c1 = Apple::new;
Apple a1 = c1.get();

Supplier<Apple> c2 = () -> new Apple();
Apple a2 = c2.get();
Function<Integer, Apple> c3 = Apple::new;
Apple a3 = c3.apply(100);

Function<Integer, Apple> c4 = (weight) -> new Apple(weight);
Apple a4 = c4.apply(100);
public List<Apple> map(List<Integer> list, Function<Integer, Apple> f){
    List<Apple> result = new ArrayList<>();
    for (Integer i : list){
        result.add(f.apply(i));
    }
    return result;
}
List<Integer> weights = Arrays.asList(1, 2, 3, 4);
List<Apple> apples = map(weights, Apple::new);

 

์ƒ์„ฑ์ž ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ ํ•˜๋‚˜์ผ ๋•, Function, ์ƒ์„ฑ์ž๊ฐ€ ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ ๋‘ ๊ฐœ์ผ ๋• BiFunction ์ธํ„ฐํŽ˜์ด์Šค๋กœ ์ƒ์„ฑ๋˜์ง€๋งŒ, ์„ธ ๊ฐœ ์ด์ƒ์˜ ์ธ์ˆ˜๋ฅผ ๊ฐ€์ง€๋Š” ์ƒ์„ฑ์ž์˜ ์ƒ์„ฑ์ž ์ฐธ์กฐ๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด, ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์ด ์—†์œผ๋ฏ€๋กœ ์ง์ ‘ ๋งŒ๋“ค์–ด์„œ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.

 

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

์ž๋ฐ”8 API์˜ ๋ช‡๋ช‡ ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๋Š” ๋‹ค์–‘ํ•œ ์œ ํ‹ธ๋ฆฌํ‹ฐ ๋ฉ”์†Œ๋“œ๋ฅผ ํฌํ•จํ•œ๋‹ค. ๊ฐ„๋‹จํ•œ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๋žŒ๋‹ค ํ‘œํ˜„์‹์„ ์กฐํ•ฉํ•ด์„œ ๋ณต์žกํ•œ ๋žŒ๋‹ค ํ‘œํ˜„์‹์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.

 

Comparator ์กฐํ•ฉ

์—ญ์ •๋ ฌ

inventory.sort(Comparator.comparing(Apple::getWeight).reversed());

comparing๋„ Comparator<T>๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ , reversed๋„ Comparator<T>๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

 

Comparator ์—ฐ๊ฒฐ

inventory.sort(Comparator.comparing(Apple::getWeight)
                .thenComparing(Apple::getColor));

 

Predicate ์กฐํ•ฉ

Predicate ์ธํ„ฐํŽ˜์ด์Šค๋Š” ๋ณต์žกํ•œ ํ”„๋ ˆ๋””์ผ€์ดํŠธ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋„๋ก negate(๋ถ€์ •), and, or ์„ธ ๊ฐ€์ง€ ๋ฉ”์†Œ๋“œ๋ฅผ ์ œ๊ณตํ•œ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด '๋นจ๊ฐ„์ƒ‰์ด ์•„๋‹Œ ์‚ฌ๊ณผ'์ฒ˜๋Ÿผ ํŠน์ • ํ”„๋ ˆ๋””์ผ€์ดํŠธ๋ฅผ ๋ฐ˜์ „์‹œํ‚ฌ ๋•Œ, negate ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

Predicate<Apple> redApple = (Apple a1) -> a1.getColor().equals(Color.RED);
Predicate<Apple> notRedApple = redApple.negate();

 

๋นจ๊ฐ›๊ณ , ๋ฌด๊ฑฐ์šด ์‚ฌ๊ณผ๋ฅผ ์œ„ํ•œ Predicate๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด and๋กœ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

Predicate<Apple> redAndHeavyApple = redApple.and(apple -> apple.getWeight() > 100);

 

๋‹จ์ˆœํ•œ ๋žŒ๋‹ค ํ‘œํ˜„์‹์„ ์กฐํ•ฉํ•ด์„œ ๋ณต์žกํ•œ ๋žŒ๋‹ค ํ‘œํ˜„์‹์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ด ์žฅ์ ์ด๋‹ค.

 

Function ์กฐํ•ฉ

Function<Integer, Integer> f = x -> x + 1;
Function<Integer, Integer> g = x -> x * 10;
Function<Integer, Integer> h = f.andThen(g);
int result = h.apply(3);

์œ„ ๊ฒฐ๊ณผ๋Š” h = g(f(x))์ด๋‹ค.

 

Function<Integer, Integer> f = x -> x + 1;
Function<Integer, Integer> g = x -> x * 10;
Function<Integer, Integer> h = f.compose(g);
int result = h.apply(3);

์œ„ ๊ฒฐ๊ณผ๋Š” h = f(g(x))์ด๋‹ค.

 

'Predicate, Comparator, Function ๋ชจ๋‘ ํ‹€๋งŒ ์žก๊ณ , ์‹ค์ œ ์‚ฌ์šฉ์€ ์ถ”์ƒ ๋ฉ”์†Œ๋“œ๋กœ ํ•œ๋‹ค'