QUIZ 2 - Modern-Java-in-Action/Online-Study GitHub Wiki

생성자 참조

    @FunctionalInterface
    public interface TriFunction<T , U , V , R> {
        R get(T t, U u, V v);
    }

    class Apple{
        int weight;
        Color color;
        String status;
        int objectHashCode = this.hashCode();

        public Apple() {
        }
        public Apple(int weight) {
            this.weight = weight;
        }
        public Apple(int weight, Color color) {
            this.weight = weight;
            this.color = color;
        }
        public Apple(int weight, String status) {
            this.weight = weight;
            this.status = status;
        }
        public Apple(int weight, Color color, String status) {
            this.weight = weight;
            this.color = color;
            this.status = status;
        }

        @Override
        public String toString() {
            return "Apple{" +
                    "weight=" + weight +
                    ", color='" + color + '\'' +
                    ", status='" + status + '\'' +
                    ", objectHashCode=" + objectHashCode +
                    '}';
        }
        public enum Color {GREEN , RED , YELLOW}
    }

    class Main {
        public static void main(String[] args) throws Exception {
            run();

            Supplier<Apple> supplier1 = Apple::new;
            System.out.println(supplier1.get());

            Supplier<Apple> supplier2 = () -> new Apple();
            System.out.println(supplier2.get());

            Function<Integer , Apple> function1 = Apple::new;
            System.out.println(function1.apply(11));

            List<Integer> weights = Arrays.asList(21 , 22 , 23 , 24 , 25);
            List<Apple> apples = map(weights , function1);
            apples.forEach(System.out::println);

            BiFunction<Integer , Apple.Color, Apple> biFunction1 = Apple::new;
            System.out.println(biFunction1.apply(31 , Apple.Color.GREEN));

            BiFunction<Integer , String , Apple> biFunction2 = Apple::new;
            System.out.println(biFunction2.apply(41 , "GOOD"));

            TriFunction<Integer , Apple.Color , String , Apple> triFunction1 = Apple::new;
            System.out.println(triFunction1.get(51 , Apple.Color.RED , "BAD"));

    //        Apple{weight=0, color='null', status='null', objectHashCode=1854731462}
    //        Apple{weight=0, color='null', status='null', objectHashCode=214126413}
    //        Apple{weight=11, color='null', status='null', objectHashCode=1867750575}
    //        Apple{weight=21, color='null', status='null', objectHashCode=2046562095}
    //        Apple{weight=22, color='null', status='null', objectHashCode=1342443276}
    //        Apple{weight=23, color='null', status='null', objectHashCode=769287236}
    //        Apple{weight=24, color='null', status='null', objectHashCode=1587487668}
    //        Apple{weight=25, color='null', status='null', objectHashCode=1199823423}
    //        Apple{weight=31, color='GREEN', status='null', objectHashCode=1896277646}
    //        Apple{weight=41, color='null', status='GOOD', objectHashCode=1702297201}
    //        Apple{weight=51, color='RED', status='BAD', objectHashCode=1296064247}

        }

        public static 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;
        }
    }
  • ✋ 같은 람다 , 다른 함수형 인터페이스
    Comparator<Apple> c1 = 
                    (Apple a1 , Apple a2) -> a1.getWeight().compareTo(a2.getWeight());
    ToIntBiFunction<Apple , Apple> c2 = 
                    (Apple a1 , Apple a2) -> a1.getWeight().compareTo(a2.getWeight());
    BiFunction<Apple , Apple , Integer> c3 = 
                    (Apple a1 , Apple a2) -> a1.getWeight().compareTo(a2.getWeight());

람다 조합 Comparator , Predicate

public class ClassForStreamAPIPractice {
    private Integer id;
    private String title;
    private boolean closed;
}

        Comparator<ClassForStreamAPIPractice> idASC = (o1 , o2) -> o1.getId().compareTo(o2.getId());

        List<ClassForStreamAPIPractice> list = new ArrayList<>();
        list.add(new ClassForStreamAPIPractice(10 , "H" , false));
        list.add(new ClassForStreamAPIPractice(10 , "A" , true));
        list.add(new ClassForStreamAPIPractice(50 , "B" , true));
        list.add(new ClassForStreamAPIPractice(20 , "G" , true));
        list.add(new ClassForStreamAPIPractice(90 , "D" , false));
        list.add(new ClassForStreamAPIPractice(80 , "E" , false));
        list.add(new ClassForStreamAPIPractice(20 , "C" , false));
        list.add(new ClassForStreamAPIPractice(50 , "F" , true));
        list.add(new ClassForStreamAPIPractice(50 , "AA" , true));
        list.add(new ClassForStreamAPIPractice(30 , "BB" , true));
        list.add(new ClassForStreamAPIPractice(40 , "CC" , true));
        list.add(new ClassForStreamAPIPractice(70 , "GG" , true));
        list.add(new ClassForStreamAPIPractice(20 , "EE" , true));

        System.out.println("id 별로 정렬");
        list.sort(Comparator.comparing(ClassForStreamAPIPractice::getId));
        list.forEach(System.out::println);

        System.out.println("id 내림차순 정렬 , id가 같다면 title 오름차순 정렬");
        list.sort(idASC.reversed().thenComparing(ClassForStreamAPIPractice::getTitle));
        list.forEach(System.out::println);

        System.out.println("title 길이가 2이상이고 , 마감된것들 필터 , id 별로 정렬");
        Predicate<ClassForStreamAPIPractice> titleLength = (e -> e.getTitle().length() >= 2);
        Predicate<ClassForStreamAPIPractice> titleLengthAndClose = titleLength.and(ClassForStreamAPIPractice::isClosed);
        List<ClassForStreamAPIPractice> result1 = list.stream()
                                                        .filter(titleLengthAndClose)
                                                        .sorted(idASC)
                                                        .collect(Collectors.toList());
        result1.forEach(System.out::println);

        System.out.println("title 길이가 2미만");
        List<ClassForStreamAPIPractice> result2 = list.stream()
                .filter(titleLength.negate())
                .collect(Collectors.toList());
        result2.forEach(System.out::println);

람다 표현식 , 익명 클래스 , 내부 클래스 지역 변수 참조

1.

    private static void run(){
        int baseNumber = 10;

        // 람다 표현식 지역 변수 참조
        IntConsumer printInt = (i) -> {
            System.out.println("람다 표현식 지역 변수 참조 : " + (i + baseNumber));
        };
        printInt.accept(10);


        // 익명 클래스에서 지역 변수 참조
        Consumer<Integer> test2 = new Consumer<Integer>() {
            @Override
            public void accept(Integer integer) {
                System.out.println("익명 클래스에서 지역 변수 참조 : " + (integer + baseNumber));
            }
        };
        test2.accept(10);

        // 내부 클래스에서 지역 변수 참조
        class LocalClass{
            void printBaseNumber(int value){
                System.out.println("내부(로컬) 클래스에서 지역 변수 참조 : " + (value + baseNumber));
            }
        }
        LocalClass test3 = new LocalClass();
        test3.printBaseNumber(10);
    }

2.

    private static void run(){
        int baseNumber = 10;

        // 람다 표현식 지역 변수 참조
        IntConsumer printInt = (i) -> {
            int baseNumber = 90;
            System.out.println("람다 표현식 지역 변수 참조 : " + (i + baseNumber));
        };
        printInt.accept(10);


        // 익명 클래스에서 지역 변수 참조
        Consumer<Integer> test2 = new Consumer<Integer>() {
            @Override
            public void accept(Integer integer) {
                int baseNumber = 90;
                System.out.println("익명 클래스에서 지역 변수 참조 : " + (integer + baseNumber));
            }
        };
        test2.accept(10);

        // 내부 클래스에서 지역 변수 참조
        class LocalClass{
            void printBaseNumber(int value){
                int baseNumber = 90;
                System.out.println("내부(로컬) 클래스에서 지역 변수 참조 : " + (value + baseNumber));
            }
        }
        LocalClass test3 = new LocalClass();
        test3.printBaseNumber(10);
    }
  • 실행 결과는??

예제 출처

    List<List<String>> persons = Arrays.asList(
        Arrays.asList("김프로,축구:농구:야구,구기종목 좋아요".split(",")),
        Arrays.asList("정프로,개발:당구:족구,개발하는데 뛰긴 싫어".split(",")),
        Arrays.asList("앙몬드,피아노, 죠르디가 좋아요 좋아좋아너무좋아".split(",")),
        Arrays.asList("죠르디,스포츠댄스:개발,개발하는 죠르디".split(","))
    );
  • 취미별 인원 수
Map<String, Integer> result = new HashMap<>();

persons.stream()
        .flatMap(member -> Arrays.stream(member.get(1).split(":")))
        .forEach(hobby -> result.merge(hobby , 1 , (oldValue , newValue) -> ++oldValue));

result.entrySet().forEach(entry-> System.out.println(entry.getKey() + " " + entry.getValue()));

//		스포츠댄스 1
//		족구 1
//		당구 1
//		개발 2
//		야구 1
//		피아노 1
//		농구 1
//		축구 1
  • Map의 merge
    default V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
        Objects.requireNonNull(remappingFunction);
        Objects.requireNonNull(value);
        V oldValue = get(key);
        V newValue = (oldValue == null) ? value :
                   remappingFunction.apply(oldValue, value);
        if (newValue == null) {
            remove(key);
        } else {
            put(key, newValue);
        }
        return newValue;
    }
  • 취미별 정씨 성을 갖는 멤버 수
    Map<String, Integer> result = new HashMap<>(); 
    persons.stream()
            .filter(member-> member.get(0).startsWith("정"))
            .flatMap(member -> Arrays.stream(member.get(1).split(":")))
            .forEach(hobby -> result.merge(hobby, 1, (oldValue, newValue) -> ++oldValue));
    
    result.entrySet().forEach(entry-> System.out.println(entry.getKey() + " " + entry.getValue()));

//		족구 1
//		당구 1
//		개발 1
  • 소개 내용에 '좋아'가 몇 번 등장하는지 구하라
    final String word = "좋아"; 
    int result = persons.stream()
                        .map(member -> countFindString(member.get(2), word))
                        .reduce(0, Integer::sum); 
    System.out.println(word + " " + result);


private static int countFindString(String source , String target) {
    int idx = source.indexOf(target);
    if(idx == -1) {
        return 0;
    }
    else {
        return 1 + countFindString(source.substring(idx + 1) , target);
    }
}

// 좋아 5
⚠️ **GitHub.com Fallback** ⚠️