0

I am asking whether I can take a function as key for a map.

Normally, a key object for a map should have hashcode and equal methods. However, Java Function is a method object, and it does not have these two methods.

Function<String, String> quote1 = s -> "'" + s + "'";
Function<String, String> quote2 = s -> "'" + s + "'";
System.out.println(quote1.equals(quote2));  //false

so is it possible? If possible, any sample? I did not get this case by google.

If not, is there any other way to identify time-consuming Function execution result? Thanks

shijie xu
  • 1,975
  • 21
  • 52
  • 1
    `hashcode` and `equal` are implemented by Object. So it is possible to use a `Function` as a key, however the default implementation of those methods is based on the reference of the object. So two `Function` objects that are the same but have different references will appear to be different keys. – Jason Feb 21 '19 at 02:47
  • No, it is not possible. – Andreas Feb 21 '19 at 02:47
  • @Andreas So is there some way to identify time-consuming `function` execution result? – shijie xu Feb 21 '19 at 02:59
  • Measure it. Remember, execution time of a function often depends heavily on the function input, so without a particular input, you can't measure anything, and the result may not apply to any other input. – Andreas Feb 21 '19 at 03:10

2 Answers2

0

Both - quote1 and quote2 - are baked by some Java class created by compiler.

Here is another discussion how to get access to bytecode

How to get bytecode as byte array from Class

Though, it is not recommended.

What is your goal behind this question?

Alexander Pavlov
  • 2,264
  • 18
  • 25
  • The `quote` function represents some calculation, e.g. DB retrieval, and I want to cache the result by the function. The problem for me is that the `function` calculation depends on environment variables, instead of its parameters. Maybe i have to refact the design – shijie xu Feb 21 '19 at 03:36
  • Environment variables cannot be changed once application is started (i.e. changes will not be visible to app) so these do not affect result caching. – Alexander Pavlov Feb 21 '19 at 03:44
  • Still not clear why do you need to compare two functions – Alexander Pavlov Feb 21 '19 at 03:45
0

The solution is to use full-blown classes with the methods hashCode and equals implemented:

public class StringStringFunction implements Function<String, String> {
    static String id = "'+s+'";

    @Override
    public int hashCode() {
        return id.hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        return obj instanceof StringStringFunction;
    }

    @Override
    public String apply(String s) {
        return  "'" + s + "'";
    }
}

then we can write:

public static void main(String[] a) {
    Function<String, String> quote1 = new StringStringFunction();
    Function<String, String> quote2 = new StringStringFunction();
    System.out.println(quote1.equals(quote2));  //true
}
Alexei Kaigorodov
  • 13,189
  • 1
  • 21
  • 38
  • So how to write the Constructor with a `Function` parameter? e.g., `public StringStringFunction(Function fun)`? In this case, we still have problem for field memers (i.e., assigning `id` value)? – shijie xu Feb 21 '19 at 04:19
  • why do you want to write a constructor with a Function parameter? this has no sense. – Alexei Kaigorodov Feb 21 '19 at 04:53
  • Thanks. I think I have got the point. The `function` itself can not have `equal` and `hashcode` methods. So the `StringFunction` uses an indirect way.l – shijie xu Feb 21 '19 at 05:51