Sometimes you may want to have a lambda expression implementing more than one interface. This is mostly useful with marker interfaces (such as java.io.Serializable) since they don't add abstract methods.
For example, you want to create a TreeSet
with a custom Comparator
and then serialize it and send it over the network. The trivial approach:
TreeSet<Long> ts = new TreeSet<>((x, y) -> Long.compare(y, x));
doesn't work since the lambda for the comparator does not implement Serializable
. You can fix this by using intersection types and explicitly specifying that this lambda needs to be serializable:
TreeSet<Long> ts = new TreeSet<>(
(Comparator<Long> & Serializable) (x, y) -> Long.compare(y, x));
If you're frequently using intersection types (for example, if you're using a framework such as Apache Spark where almost everything has to be serializable), you can create empty interfaces and use them in your code instead:
public interface SerializableComparator extends Comparator<Long>, Serializable {}
public class CustomTreeSet {
public CustomTreeSet(SerializableComparator comparator) {}
}
This way you're guaranteed that the passed comparator will be serializable.