Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can an interface somehow prevent lambda expression implementations?

Tags:

java

lambda

Background

I am exposing the following interface as part of an API:

public interface Pasture {
    /**
     * @param t         The time of the visit (as measured from optimization starting point).
     * @param tLast     The time of the preceding visit (as measured from optimization starting point).
     * @return          The expected reward that will be reaped by visiting under the given conditions.
     */
    double yield(long t, long tLast);    
}

The client passes me models of "pastures" as objects implementing this interface. Each object represents one pasture.

On my side of the API, I keep track of "visits" to these objects at various times, then invoke pasture.yield(time, lastVisitTime) when I need to know how much the pasture would have produced in the mean time.

The problem arises that this interface can be implemented on the client side as a lambda expression, and apparently each lambda expression instantiation does not necessarily create a new object with a new identity, which is what I rely on in order to keep track of which pastures were visited at what times.

Question

Is there a way of preventing the interface from being implemented as a lambda expression, forcing instead that the client implements it as an anonymous class. Adding a dummy method to it would do the trick, of course, but that would be arbitrary and untidy in my opinion. Is there another way?

like image 433
Museful Avatar asked Aug 18 '15 08:08

Museful


2 Answers

It is not the lambda edge case that is your problem.

You are making an assumption that the same object represents the same Pasture and are therefore making your object do two things at once. That is a code smell and is the cause of your difficulties.

You should force your Pasture objects to implements something like equals so that you can then check if the items are the same. Sadly there is no interface that does that, the nearest one is Comparable.

public interface Pasture extends Comparable<Pasture> {
like image 97
OldCurmudgeon Avatar answered Oct 04 '22 15:10

OldCurmudgeon


You can add some checked exception to method:

public interface Pasture {
   double yield(long t, long tLast) throws Exception;    
}

But it is strange approach to deny lambda.

like image 21
sibnick Avatar answered Oct 04 '22 13:10

sibnick