1

I have an interface that looks like

public interface ListAbstractor
{
    List<String> getList();
    void addTo(String s);
}

I want to use it for unit tests on get/set/verify operations on a class with several List<String> get_xxxx and void addToList(String) functions. I would LIKE to declare it with the minimal amount of verbage (I'm ocd that way).

I've seen examples where interfaces (with one method) are implemented in a lovely one line lambda:

interface IntegerMath {
    int operation(int a, int b);   
}

...
IntegerMath addition = (a, b) -> a + b;

I want to implement it something like:

ListAbstractor la  = 
                new ListAbstractor()
                {
                    getList = ()-> settings.getZooKeeperList();
                    addTo = (s)-> settings.addToZookeeperList(s);
                };

but eclipse does not like this. So what is the short'n'sweetest way to do this?

4
  • There isn't. Lambda syntax only works with functional interfaces. Use the anonymous class declaration syntax (or define a named type that implements the interface). Commented Nov 10, 2015 at 17:37
  • what do you mean by "functional interface"? an interface with a single function? Commented Nov 10, 2015 at 17:40
  • docs.oracle.com/javase/8/docs/api/java/lang/… Commented Nov 10, 2015 at 17:41
  • so then "yes, an interface with a single function" Commented Nov 10, 2015 at 17:42

2 Answers 2

4

The common solution is to create a special static method in your interface to construct the instances:

import java.util.List;
import java.util.function.Consumer;
import java.util.function.Supplier;

public interface ListAbstractor {
    List<String> getList();
    void addTo(String s);

    public static ListAbstractor of(Supplier<List<String>> listSupplier,
                                    Consumer<String> adder) {
        return new ListAbstractor() {
            @Override
            public List<String> getList() {
                return listSupplier.get();
            }

            @Override
            public void addTo(String s) {
                adder.accept(s);
            }
        };
    }
}

No need to create additional functional interfaces as you may reuse standard ones. Somewhat similar approach is implemented in Collector.of static method.

Now you can write:

myTestFunction(ListAbstractor.of(settings::getZooKeeperList, settings::addToZookeeperList));
Sign up to request clarification or add additional context in comments.

1 Comment

I selected yours as the answer because it looks like the "proper" way to do it in java. I still wish there was a lighter, more anonymous way to declare the functions but that's java for you I guess.
1

What I ended up doing is breaking the interface in to two interfaces. This actually takes LESS code than what I had wanted to do, so win.

myTestFunction(()-> settings.getZooKeeperList(),
                (s)-> settings.addToZookeeperList(s));              

1 Comment

Have no idea. The question is clear and interesting. Upvoted.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.