java

자바 8 - 람다 표현식 처리

Jan 30, 2020

람다 표현식을 사용하는 자신만의 메서드 작성법을 알아보자.

목차

1. 지연 실행 구하기
2. 함수형 인터페이스 고르기
3. 자신만의 함수형 인터페이스 구현하기


1. 지연 실행 구하기

람다 표현식을 사용하는 이유는 지연실행이다. 당장 코드를 실행하고 싶다면 람다를 사용하지 않는다.

코드를 나중에 실행하는 이유

public class RepeatDemo {

    public static void main(String[] args) {
        repeat(10, () -> System.out.println("Hello World!"));
    }

    public static void repeat(int n, Runnable runnable) {
        for (int i = 0; i < n; i++) {
            runnable.run();
        }
    }
}

람다 표현식의 구현부는 runnable.run()이 호출될 때 실행된다.

int값 처리에 사용하는 표준 함수형 인터페이스인 IntConsumer로 몇 번째 반복을 수행하는지 출력한다.

public class RepeatDemo {
    ...

    public static void main(String[] args) {
        repeat(10, i -> System.out.println("Countdown : " + (9 - i)));
    }

    public static void repeat(int n, IntConsumer intConsumer) {
        for(int i = 0; i < n; i++) {
            intConsumer.accept(i);
        }
    }
}



2. 함수형 인터페이스 고르기

파일을 처리하는 메서드를 작성한다고 하자. 여기서 파일은 특정 기준을 만족해야 한다. 그럼 java.io.FileFilter 클래스와 Predicate<File> 중 권장하는 것은 Predicate이다. FileFilter 인스턴스를 만들어내서 유용하게 사용할 수 있는 메서드를 이미 갖추고 있는 경우를 제외하고는 표준 Predicate<File>을 사용한다.

기본 타입 int 용의 특화 버전들이 있다. 오토박싱을 줄이려면 특화버전을 사용하는 것이 좋다. Consumer<Integer> 대신 IntConsumer를 사용한다.



3. 자신만의 함수형 인터페이스 구현하기

표준 함수형 인터페이스가 적합하지 않은 상황에 놓이면 직접 인터페이스를 구현해야 한다.

예를 들어, 이미지를 색체 패턴으로 채운다고 하자. 사용자가 각 픽셀에 사용할 색을 넘겨주는 함수를 작성해야 한다. 그런데 (int, int) -> color 매핑에 해당하는 표준 타입은 없다. BiFunction<Integer, Integer, Color>를 사용할 수도 있지만, 오토박싱이 일어난다.

@FunctionalInterface
public interface PixelFunction {
    Color apply(int x, int y);
}
public class ImageDemo {
    public static BufferedImage createImage(int width, int height, PixelFunction f) {
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

        for (int x = 0; x < width; x++)
            for (int y = 0; y < height; y++) {
                Color color = f.apply(x, y);
                image.setRGB(x, y, color.getRGB());
            }
        return image;
    }

    public static void main(String[] args) throws IOException {
        BufferedImage frenchFlag = ImageDemo.createImage(150, 100,
                (x, y) -> x < 50 ? Color.BLUE : x < 100 ? Color.WHITE : Color.RED);
        Path path = Paths.get("flag.png");
        ImageIO.write(frenchFlag, "PNG", path.toFile());
        System.out.println("Image saved to " + path.toAbsolutePath());
    }
}