Why do suppliers only support no-arg constructors?
If the default constructor is present, I can do this:
create(Foo::new)
But if th
When looking for a solution to the parametrized Supplier
problem, I found the above answers helpful and applied the suggestions:
private static Supplier failedMessageSupplier(Function fn, String msgPrefix, String ... customMessages) {
final String msgString = new StringBuilder(msgPrefix).append(" - ").append(String.join("\n", customMessages)).toString();
return () -> fn.apply(msgString);
}
It is invoked like this:
failedMessageSupplier(String::new, msgPrefix, customMsg);
Not quite satisfied yet with the abundant static function parameter, I dug further and with Function.identity(), I came to the following result:
private final static Supplier failedMessageSupplier(final String msgPrefix, final String ... customMessages) {
final String msgString = new StringBuilder(msgPrefix).append(" - ").append(String.join("\n", customMessages)).toString();
return () -> (String)Function.identity().apply(msgString);
};
Invocation now without the static function parameter:
failedMessageSupplier(msgPrefix, customMsg)
Since Function.identity()
returns a function of the type Object
, and so does the subsequent call of apply(msgString)
, a cast to String
is required - or whatever the type, apply() is being fed with.
This method allows for e. g. using multiple parameters, dynamic string processing, string constants prefixes, suffixes and so on.
Using identity should theoretically also have a slight edge over String::new, which will always create a new string.
As Jacob Zimmerman already pointed out, the simpler parametrized form
Supplier makeFooFromString(String str1, String str2) {
return () -> new Foo(str1, str2);
}
is always possible. Whether or not this makes sense in a context, depends.
As also described above, static Method reference calls require the corresponding method's number and type of return / parameters to match the ones expected by the function-consuming (stream) method.