0

I am trying to learn lambda expression but, I could not understand what is happening in this example code.

The author is trying to explain about method chaining,

import java.util.stream.Stream;
import java.util.function.Function;
import java.awt.Color;
import java.util.function.Consumer;


class Camera {
    private Function<Color, Color> filter;

    public Color capture(final Color inputColor) {
        final Color processedColor = filter.apply(inputColor);
        // ... more processing of color...
        return processedColor;
    }

    // ... other functions that use the filter ...

    public void setFilters(final Function<Color, Color>... filters) {
        filter = Stream.of(filters).reduce((filter, next) -> filter.compose(next)).orElse(color -> color);
    }

    public Camera() {
        setFilters();
    }

    public static void main(final String[] args) {
        final Camera camera = new Camera();
        final Consumer<String> printCaptured = (filterInfo) -> System.out
                .println(String.format("with %s: %s", filterInfo, camera.capture(new Color(200, 100, 200))));

        System.out.println("//" + "START:NOFILTER_OUTPUT");
        printCaptured.accept("no filter");
        System.out.println("//" + "END:NOFILTER_OUTPUT");

        System.out.println("//" + "START:BRIGHT_OUTPUT");
        camera.setFilters(Color::brighter);
        printCaptured.accept("brighter filter");
        System.out.println("//" + "END:BRIGHT_OUTPUT");

        System.out.println("//" + "START:DARK_OUTPUT");
        camera.setFilters(Color::darker);
        printCaptured.accept("darker filter");
        System.out.println("//" + "END:DARK_OUTPUT");

        System.out.println("//" + "START:BOTH_OUTPUT");
        camera.setFilters(Color::brighter, Color::darker);
        printCaptured.accept("brighter & darker filter");
        System.out.println("//" + "END:BOTH_OUTPUT");
    }

}

Now let us consider this line: camera.setFilters(Color::brighter);

Here we get an RGB value and that is passed on the setFilters method and a stream object is created for that color. And for function to be processed there should be an apply method defined for that function and I am not knowing what is happening. Could someone please explain.

User27854
  • 824
  • 1
  • 16
  • 40
  • 1
    *"Here we get an RGB value and that is passed on the setFilters"* - no. You pass the function reference of the `brighter` method to the `setFilters` method. This is **not** method chaining, that would be `camera.setFilter(...).applyAngle(...).takePicture(...).move(...).close()`. – luk2302 Jun 11 '21 at 14:18
  • @luk2302, I got what you are telling. Let me reframe my doubt. Let us consider this line. camera.setFilters(Color::brighter, Color::darker); -> aren't we passing two color objects here? Moreover function method takes in an input parameter. But the brighter or darker method does not have any parameter defined. In that case It should be throwing error right? – User27854 Jun 11 '21 at 14:36
  • 1
    No, you are passing two function references. In layman terms: yes, they have a parameter, an implicit Color / `this` parameter to know which color to make brighter. – luk2302 Jun 11 '21 at 14:38
  • Alright, I was able to figure that out when I rewrite the code code as Function color1 = Color:: brighter;, now when it tries to execute this code i.e filter.compose(next) it will internally call the brigher/darker fucntion right? – User27854 Jun 11 '21 at 14:44

0 Answers0