ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 익명클래스 실용편
    개발/java 2022. 1. 1. 16:12

    익명클래스를 실제로 한번 사용해보겠습니다. 

     

    배경부터 설명하겠습니다. 

    사과 농장이 있습니다. 

    사과 농장에서 사과는 초록색과 , 빨간색 사과가 있습니다. 

    이를 분류하여 색마다 갯수를 추출하고 싶어서 의뢰를 한 내용입니다. 

    현재 농장에서 재배한 사과는 3개밖에 없으며 리스트에는 초록사과 2개 ,빨강사과 1개로 정의하겠습니다. 

     

    List<Apple> Apples() {
       List<Apple> apples = new ArrayList<>();
       apples.add(new Apple(Color.GREEN.name()));
       apples.add(new Apple(Color.GREEN.name()));
       apples.add(new Apple(Color.RED.name()));
       return apples;
    }

    작업 순서는 아래와 같으며 각각에 대한 코드를 설명 드리겟습니다. 

    [사과색 정의 , 사과 정의 , 색 여부 정의 , filer정의 , 구현 ]

     

    1.사과색 정의 -빨강 , 초록에 대해 enum으로 정의를 하였습니다.

    public enum Color {
        RED("red","빨강")
        ,GREEN("green","초록");
    
        private String code;
        private String value;
    
        Color(String code, String value) {
            this.code = code;
            this.value = value;
        }
    
    }

    2.사과 정의 -현재 사과에는 색말곤 변수가 없습니다. 

    @AllArgsConstructor
    @Data
    public class Apple {
        private String color;
    
    }

    3.색 여부 정의 -사과에 대한 분류를 하기 위해 boolean을 통해 참 , 거짓에 대한 인터페이스를 생성하였습니다.

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

    4.filer 정의 --사과의 리스트를 받아와서 해당 사과마다 참 여부를 판별한 후 리스트에 삽입하였습니다. 

    List<Apple> filerApples(List<Apple>apples , ApplePredicate p) {
       List<Apple> result = new ArrayList<>();
       for (Apple apple : apples) {
          if (p.test(apple)) {
             result.add(apple);
          }
       }
       return result;
    }

    5.구현 --현 요청은 초록 사과 리스트의 사이즈를 구하는 것이므로 참 거짓 인터페이스에 초록 여부를 판별하는 익명클래스를 생성하였습니다.

    @Test
    void filerGreenApples() {
       List<Apple> apples = Apples();
       List<Apple> greenApples  = filerApples(apples, new ApplePredicate() {
          @Override
          public boolean test(Apple apple) {
             return Color.GREEN.name().equals(apple.getColor());
          }
       });
       System.out.println(greenApples.size());
    
    }

     

    cf)

    인터페이스 구현 이유 : 여러 조건이 추가될수 있기 때문입니다. 

    예를 들면 현재는 색으로만 구분을 요청하였는데 추후 추가 되어 무게 , 농장위치 등 다양한 조건과 혼합하여 정의가 변경 될 수 있기 때문에 이를 인터페이스로 구현하였고 만약 요구사항이 변경 될경우 각각에 케이스에 대해서 익명 클래스로 기존 로직에 대한 변경 없이 구현할 수 있습니다. 

    익명클래스 사용 이유 : ApplePredicate를 상속받은 클래스를 생성하면 의미없는 클래스의 생성

    예를 들면  filerApples 메서드를 사용함에 있어 익명 클래스가 아닌 아래와 같은 ApplePredicate를 상속받은 클래스를 만들고 사이즈 정의 메서드에서 GreenApplePredicate를 사용하면 됩니다. 그러나 케이스가 많을 수록 이를 계속 생성해야하는 문제점이 있습니다. 

    public class GreenApplePredicate implements ApplePredicate {
        @Override
        public boolean test(Apple apple) {
            return Color.GREEN.name().equals(apple.getColor());
        }
    }
    @Test
    void filerGreenApplesTwo() {
       List<Apple> apples = Apples();
       List<Apple> greenApples  = filerApples(apples, new GreenApplePredicate());
       System.out.println(greenApples.size());
    
    }

     

    여담) 

    우리는 test()에 해당하는 메서드 부분만 필요하기 때문에 안써도 될것 같은 부분들이 있습니다. 

    그러므로 자바에서는 람다를 생성하였고 위의 코드는 아래와 같이 람다를 통해 좀 더 명확한 코드로 생성할 수 있습니다. 

    @Test
    void LamdaFilerGreenApples() {
       List<Apple> apples = Apples();
       List<Apple> greenApples  = filerApples(apples,
             (Apple apple)->Color.GREEN.name().equals(apple.getColor())
       );
       System.out.println(greenApples.size());
    
    }

    제네릭 타입인자를 통해 사과 뿐만 아니라 기타 여러 조건도 포함되게 할 수 잇습니다. 

    <T> List<T> filerType(List<T> list , Predicate<T> p) {
       List<T> result = new ArrayList<>();
       for (T e : list) {
          if (p.test(e)) {
             result.add(e);
          }
       }
       return result;
    }
    @Test
    void filerGreenType() {
       List<Apple> apples = Apples();
       List<Apple> greenApples  = filerType(apples,  (Apple apple)->Color.GREEN.name().equals(apple.getColor()));
       System.out.println(greenApples.size());
    
    }

    '개발 > java' 카테고리의 다른 글

    RESTAPI 이력감지  (0) 2024.08.19
    map vs flatmap  (0) 2022.01.04
    익명클래스  (1) 2022.01.01
    stream vs parallelStream  (0) 2021.12.30
    초기화블록  (0) 2021.12.25

    댓글

Designed by Tistory.