6

I have some code which looks like the below:

import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;

class MyObj {
    private final Double aDouble;

    public MyObj(Double aDouble) {
        this.aDouble = aDouble;
    }
}

class Main {
    public static void main(String[] args) {
        List<Function<MyObj, String>> functionList1 = new ArrayList<>();
        List<Function<MyObj, String>> functionList2 = new ArrayList<>();

        // ... Add same Function<MyObj, String>s to both lists

        // I want to assert that functionList1.equals functionList2
    }
}

I'd like to check that some Function, Supplier, BiFunction or whatever it might be of MyObj, would be equal to another if the result of calling the Function/Supplier etc returns the same value given the same input.

So in this case, Java would compare the values of the two lists using equals like so functionList1.get(0).apply(standardInstanceOfMyObj) equals functionList2.get(0).apply(standardInstanceOfMyObj) etc.

My question is, how can I override equals and hashcode for a specific type like Function<MyObj, String> to make the above work?

  • 2
    Why do you want to override the methods for the function, rather than your data type? – jrtapsell Oct 24 '17 at 14:16
  • 1
    Well, two functions might return the same value for parameter `a`, but different values for parameter `b`. How are you going to handle that? – Sweeper Oct 24 '17 at 14:17
  • 1
    Why do you want to do those checks? If it is for any kind of testing (your use of "assert" suggests that), you should probably keep to the methods provided by a testing framework. equals() and hashcode() are meant for equality of state, not for equality of functionality. – Rüdiger Schulz Oct 24 '17 at 14:18
  • it's not for testing but more as a way to pass the Function object around so it can be chained and applied at the appropriate times. But I take your point, there probably is a better way to design this than to compare Functions. – two_stacks_one_heap Oct 24 '17 at 14:36
  • 3
    There is nothing special about the `Function` interface. You can create a class which implements this interface and declares an `equals` and `hashCode` method. You can’t control the equality of lambda expressions or method references, but within your question, neither of these terms appears, so it’s not clear whether they are related to your question or not. Taking your question as-is, the answer is that you can do it just like with any other interface. – Holger Oct 24 '17 at 14:54

1 Answers1

7

You can't. You can, however, override them for any class of yours that does actually implement Function. Comparing functions (mathematically) is tricky business since the domain space might be infinite, so Java would have no way to know that two functions are the same (other than in the case of numerical identity, where equals() will be true anyway). If you have some specific functions for which you can provide a more fine-grained equals()/hashCode() (for example, because they are based on some parsed expression language and you can compare the string representations), then you'll have to write those criteria in your own class.

Piotr Wilkin
  • 3,446
  • 10
  • 18