Search code examples
javalambdajava-8functional-interface

How the Lambda in static method instantiates the interface


I've been doing java for some time, due to corporate and personal inertia, mostly java 1.7. Recently I decided to start learning a bit more about the functional side o java, so I started playing with the Function interface and building a Validator that would check if a Map would match the Validator criteria. So that the Validator could be built programatically like

Usage:

Map<String, String> book = new LinkedHashMap<String, String>();

book.put("Title", "Leviathan Wakes");
book.put("Subject", "A proto molecule");
book.put("Category", "sci-fi");
book.put("TotalPages", "350")

final ResourceValidator filter = ResourceValidator.containsProperty("Title").and(ResourceValidator.containsProperty("Category"));
assert filter.apply(book);

This is code I've produced

    public interface ResourceValidator extends Function<Map<String,String>,Boolean> {
    
    static ResourceValidator containsProperty(String property) {
            return resource -> resource.containsKey(property);
        }

    default ResourceValidator and(ResourceValidator other){
        return resource -> this.apply(resource) && other.apply(resource);
    }
}

So far it seems to be behaving as expected, what I can't understand is how the interface gets instantiated. The call to

final ResourceValidator filter = ResourceValidator.containsProperty("Title");

calls static method of the interface, how and where in the static method is ResourceValidator instantiated?

static ResourceValidator containsProperty(String property) {
            return resource -> resource.containsKey(property);
        }

I've been looking and I'm struggling to find an answer


Solution

  • You provided the implementation of those static methods. For example; when you created a lambda as resource -> resource.containsKey(property), what you essentially did was;

     return new ResourceValidator() {
                @Override
                public Boolean apply(Map<String, String> resource) {
                    return resource.containsKey(property);
                }
            };
    

    you implemented the apply of ResourceValidator function (is subtype of Function interface, which is marked as a functional interface).

    So now you could invoke it like;

    ResourceValidator.containsProperty("foo").apply(Map.of("foo", "bar"));

    You may have come across Java lambda expressions. Otherwise, this is quite comprehensive https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html,