Java – guava why is tostringfunction not a generic function?
Guava tostringfunction() has the following Declaration:
public static Function<Object,String> toStringFunction() { ... }
Object, so this function works well
But when I try to combine it with another function, for example:
Function<Integer,Double> f1 = Functions.compose(Functions.forMap(someMap),Functions.toStringFunction());
The somemap variable is map < string, double >, so I want tostringfunction to convert integer to string, and then formap to convert string to double But I received a compilation error:
Function<Integer,^ required: Function<Integer,Double> found: Function<Object,Double> 2 errors
My two questions are:
1. Specifically tell the compiler that tostringfunction should be function < integer, string >? A simple actor won't work. I'm looking for a real combination of these two functions
Function< Integer,String> g1 = (Function< Integer,String>)Functions.toStringFunction(); // cause error
2. Write tostringfunction as follows:
@SuppressWarnings("unchecked") public static <E> Function<E,String> toStringFunction(){ return (Function<E,String>) ToStringFunction.INSTANCE; } // enum singleton pattern private enum ToStringFunction implements Function<Object,String>{ INSTANCE; // @Override public String toString(){ // return "Functions.toStringFunction()"; // } @Override public String apply(Object o){ return o.toString(); } }
I can specify the type:
Function<Integer,Functions.<Integer>toStringFunction());
It works well But what is the motivation for the version that the guava team now has?
Solution
After comments and discussion:
To fix compilation errors:
Function<Object,Double> f1 = Functions.compose(Functions.forMap(someMap),Functions.toStringFunction());
Your question means that you need a function < integer, double > instead of a function < object, double > Based on the discussion in the comments and trying to consider other options, the only reason you want this is verification The code in tostringfunction is not under your control, so validation in this function is impossible As for the validation in the formap function, the code is beyond your control If you want to prevent illegalargumentexception, you must perform this verification whether the input you provide is object or integer Therefore, validation is also beyond the scope of formap, tostringfunction and compose, because these functions do not provide such validation. You must write your own code to perform this operation (catch exceptions and handle them or pre validate in some way before calling this composite function)
For a specific combination, you can get nothing by changing the input parameter of function from object to integer. Because function only needs the methods in object, this is a good decision because it simplifies things in this case and makes it more widely available Assuming you can force the parameter type to integer, you still won't get any benefit, whether it's the verification of illegalargumentexception or anything else you're trying
When designing an API, you want as many consumers as possible to use it without deviating from your approach, that is, you should use the highest level of classes that meet your requirements By using object in tostringfunction, guava function satisfies this principle This makes the function more general and can be used more widely This is why object is selected instead of parameterizing this function
If a function accepts an argument, it won't do it now, so why use an argument when it's not needed This method greatly simplifies the design, rather than adding unnecessary things
Original answer:
Each class is a subclass of object. Function only calls toString on the input existing in the object class Therefore, in this case, declaring a function is equivalent to declaring a function By changing the input parameter of function from object to integer, you will not get any results because it simplifies things in this case
You should use the highest level courses that meet your requirements as much as possible This makes the function more general and can be used more widely This is why object is selected instead of parameterizing this function
Fix compilation errors: function F1 = functions compose(Functions.forMap(someMap),Functions. toStringFunction());