๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

Dev Book Review/Java8 in Action

[์ž๋ฐ”8์ธ์•ก์…˜] Chap.2 ๋™์ž‘ ํŒŒ๋ผ๋ฏธํ„ฐํ™” ์ฝ”๋“œ ์ „๋‹ฌํ•˜๊ธฐ

์†Œ์Šค์ฝ”๋“œ

https://github.com/mjung1798/Jyami-Java-Lab/tree/master/java8-in-action

 

mjung1798/Jyami-Java-Lab

๐Ÿ’ป Jyami์˜ Spring boot ๋ฐ Java ์‹คํ—˜์†Œ ๐Ÿ’ป. Contribute to mjung1798/Jyami-Java-Lab development by creating an account on GitHub.

github.com

 

๋™์ž‘ ํŒŒ๋ผ๋ฏธํ„ฐํ™” : ์•„์ง์€ ์–ด๋–ป๊ฒŒ ์‹คํ–‰ํ•  ๊ฒƒ์ธ์ง€ ๊ฒฐ์ •ํ•˜์ง€ ์•Š์€ ์ฝ”๋“œ ๋ธ”๋ก, ์ฝ”๋“œ ๋ธ”๋ก์˜ ์‹คํ–‰์€ ๋‚˜์ค‘์œผ๋กœ ๋ฏธ๋ค„์ง„๋‹ค.

๋ณ€ํ™”ํ•˜๋Š” ์š”๊ตฌ์‚ฌํ•ญ์— ์œ ์—ฐํ•˜๊ฒŒ ๋Œ€์‘ํ•  ์ˆ˜ ์žˆ๊ฒŒ ์ฝ”๋“œ๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•

  • ๋ฆฌ์ŠคํŠธ์˜ ๋ชจ๋“  ์š”์†Œ์— '์–ด๋–ค ๋™์ž‘'์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Œ
  • ๋ฆฌ์ŠคํŠธ ๊ด€๋ จ ์ž‘์—…์„ ๋๋‚ธ ๋‹ค์Œ์— '์–ด๋–ค ๋‹ค๋ฅธ ๋™์ž‘'์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Œ
  • ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด '์ •ํ•ด์ง„ ์–ด๋–ค ๋‹ค๋ฅธ ๋™์ž‘'์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Œ

 

1. ๋ณ€ํ™”ํ•˜๋Š” ์š”๊ตฌ์‚ฌํ•ญ์— ๋Œ€์‘ํ•˜๊ธฐ

DRY(don't repeat yourself) : ๊ฐ™์€ ๊ฒƒ์„ ๋ฐ˜๋ณตํ•˜์ง€ ๋ง๊ฒƒ.

๋ฌธ์ž์—ด, ์ •์ˆ˜, ๋ถˆ๋ฆฐ ๋“ฑ์˜ ๊ฐ’์œผ๋กœ ๋ฉ”์„œ๋“œ๋ฅผ ํŒŒ๋ผ๋ฏธํ„ฐํ™” ํ•  ๋•Œ => ํ•œ์ค„์ด ์•„๋‹ˆ๋ผ ๋ฉ”์„œ๋“œ ์ „์ฒด ๊ตฌํ˜„์„ ๋ฐ”๊พธ์–ด์•ผ ํ•œ๋‹ค.

๋…น์ƒ‰ ์‚ฌ๊ณผ ํ•„ํ„ฐ๋ง filterGreenApples(List<Apple> inventory)
-> ์ƒ‰์— ๋”ฐ๋ฅธ ํ•„ํ„ฐ๋ง filterApplyByColor(List<Apple> inventory, String color)
-> ์†์„ฑ ํ•„ํ„ฐ๋ง filterApples(List<Apple> inventory, String color, int wieght, boolean flag)

๋ณ„๋กœ๋‹ค

 

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

ํ”„๋ ˆ๋””์ผ€์ดํŠธ Predicate : ์„ ํƒ ์กฐ๊ฑด์„ ๊ฒฐ์ •ํ•˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค => ์–ด๋–ค ์†์„ฑ์— ๊ธฐ์ดˆํ•ด์„œ ๋ถˆ๋ฆฐ๊ฐ’์„ ๋ฐ˜ํ™˜

์ „๋žต ๋””์ž์ธ ํŒจํ„ด(strategy design pattern)

  • ๊ฐ ์•Œ๊ณ ๋ฆฌ์ฆ˜(์ „๋žต์ด๋ผ ๋ถˆ๋ฆฌ๋Š”)์„ ์บก์Šํ™”ํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜ ํŒจ๋ฐ€๋ฆฌ๋ฅผ ์ •์˜ํ•ด๋‘” ๋‹ค์Œ์— ๋Ÿฐํƒ€์ž„์— ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์„ ํƒํ•˜๋Š” ๊ธฐ๋ฒ•
  • ๊ฐ์ฒด๊ฐ€ ํ•  ์ˆ˜ ์žˆ๋Š” ํ–‰์œ„๋ฅผ ์ „๋žต์œผ๋กœ ๋งŒ๋“ค๊ณ  ๋™์ ์œผ๋กœ ํ–‰์œ„์˜ ์ˆ˜์ •์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ ์ „๋žต์œผ๋กœ ๋ฐ”๊พธ๋Š” ๊ฒƒ๋งŒ์œผ๋กœ๋„ ํ–‰์œ„์˜ ์ˆ˜์ •์ด ๊ฐ€๋Šฅํ•˜๋„๋ก ๋งŒ๋“  ํŒจํ„ด
public interface ApplePredicate{
  boolean test(Apple apple); 
}

public class AppleGreenColorPredicate implements ApplePredicate {
    @Override
    public boolean test(Apple apple) {
        return "green".equals(apple.getColor());
    }
}

public class AppleHeavyWeightPredicate implements ApplePredicate{
    @Override
    public boolean test(Apple apple) {
        return apple.getWeight() > 150;
    }
}

๋™์ž‘ ํŒŒ๋ผ๋ฏธํ„ฐํ™” : ๋ฉ”์„œ๋“œ๊ฐ€ ๋‹ค์–‘ํ•œ ๋™์ž‘(์ „๋žต)์„ ๋ฐ›์•„์„œ ๋‚ด๋ถ€์ ์œผ๋กœ ๋‹ค์–‘ํ•œ ๋™์ž‘์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

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;
}

List<Apple> heavyApples = FilteringApple.filterApples(inventory, new AppleHeavyWeightPredicate());
List<Apple> greenApples = FilteringApple.filterApples(inventory, new AppleGreenColorPredicate());

๋‚ด๊ฐ€ ์ „๋‹ฌํ•œ ApplePredicate ๊ฐ์ฒด์— ์˜ํ•ด filterApples ๋ฉ”์„œ๋“œ์˜ ๋™์ž‘์ด ๊ฒฐ์ •๋œ๋‹ค.

ํ•œ ๋ฉ”์„œ๋“œ๊ฐ€ ๋‹ค๋ฅธ ๋™์ž‘์„ ์ˆ˜ํ–‰ํ•˜๋„๋ก ์žฌํ™œ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค : ํ•œ๊ฐœ์˜ ํŒŒ๋ผ๋ฏธํ„ฐ ๋‹ค์–‘ํ•œ ๋™์ž‘

 

3. ๊ฐ„์†Œํ™” ํ•˜๊ธฐ

a. ์ต๋ช… ํด๋ž˜์Šค

์ต๋ช…ํด๋ž˜์Šค(anonymous class) ๊ธฐ๋ฒ• : ํด๋ž˜์Šค์˜ ์„ ์–ธ๊ณผ ์ธ์Šคํ„ด์Šคํ™”๋ฅผ ๋™์‹œ์— ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋ฒ•

ํด๋ž˜์Šค ์„ ์–ธ๊ณผ ์ธ์Šคํ„ด์Šคํ™”๋ฅผ ๋™์‹œ์— ํ•  ์ˆ˜ ์žˆ๋‹ค == ์ฆ‰์„์—์„œ ํ•„์š”ํ•œ ๊ตฌํ˜„์„ ๋งŒ๋“ค์–ด์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

Predicate ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ํด๋ž˜์Šค ๋งŒ๋“ค์–ด์„œ ์ธ์Šคํ„ด์Šค ํ™” ํ•ด์•ผํ•œ๋‹ค (๊ท€์ฐฎ์Œ)

List<Apple> redApples = FilteringApple.filterApples(inventory, new ApplePredicate() {
  @Override
  public boolean test(Apple apple) {
    return "red".equals(apple.getColor());
  }
});
assertThat(redApples.size()).isEqualTo(2);

๊ทธ๋Ÿฌ๋‚˜ ์žฅํ™ฉํ•˜๋‹ค : ๋‚˜์˜๋‹ค!

๋žŒ๋‹ค ํ‘œํ˜„์‹์œผ๋กœ ์ฝ”๋“œ๋ฅผ ๋” ๊ฐ„๊ฒฐํ•˜๊ฒŒ ์ •๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

b. ๋žŒ๋‹ค ํ‘œํ˜„์‹

List<Apple> redApples = FilteringApple.filterApples(inventory, apple -> "red".equals(apple.getColor()));

์œ ์—ฐํ•จ๊ณผ ๊ฐ„๊ฒฐํ•จ ๋‘๊ฐ€์ง€๋ฅผ ๋ชจ๋‘ ๊ฐ€์ ธ๊ฐ„๋‹ค!

c. ํ˜•์‹ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์ด์šฉํ•œ ์ถ”์ƒํ™”

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;
}

d. ์ข…ํ•ฉ: ๋™์ž‘ ํŒŒ๋ผ๋ฏธํ„ฐํ™”์˜ 3๊ฐ€์ง€ ๋ฐฉ๋ฒ•

  • ํด๋ž˜์Šค
  • ์ต๋ช… ํด๋ž˜์Šค
  • ๋žŒ๋‹ค

 

5. ์‹ค์ „ ์˜ˆ์ œ

a. Comparator ์ •๋ ฌ

sort ๋™์ž‘์„ ํŒŒ๋ผ๋ฏธํ„ฐํ™” ํ•  ์ˆ˜ ์žˆ๋‹ค.

// ์ต๋ช…ํด๋ž˜์Šค ์ด์šฉ
inventory.sort(new Comparator<Apple>() {
  @Override
  public int compare(Apple o1, Apple o2) {
    return o1.getWeight().compareTo(o2.getWeight());
  }
});
// ๋žŒ๋‹ค์‹ ์ด์šฉ
inventory.sort((a1, a2)->a1.getWeight().compareTo(a2.getWeight()));

b. Runnable ์ฝ”๋“œ ๋ธ”๋ก ์‹คํ–‰

// ์ต๋ช…ํด๋ž˜์Šค ์ด์šฉ
Thread t1 = new Thread(new Runnable() {
  @Override
  public void run() {
    System.out.println("helloWorld");
  }
});
t1.run();
// ๋žŒ๋‹ค์‹ ์ด์šฉ
Thread t2 = new Thread(() -> System.out.println("helloWorld"));
t2.run();