varargs as input parameter to a function in java 8 - java

In Java 8, how is a Function is defined to fit varargs.
we have a function like this:
private String doSomethingWithArray(String... a){
//// do something
return "";
}
And for some reason I need to call it using Java 8 function (because 'andThen' can be used along with other functions.)
And thus I wanted to define it something as given below.
Function<String... , String> doWork = a-> doSomethingWithArray(a) ;
That gives me compilation error.Following works, but input is now has to be an array and can not be a single string.
Function<String[] , String> doWork = a-> doSomethingWithArray(a) ;
Here I mentioned String, but it can be an array of any Object.
Is there a way to use varargs(...)instead of array([]) as input parameter?
Or if I create a new interface similar to Function, is it possible to create something like below?
#FunctionalInterface
interface MyFunction<T... , R> {
//..
}

You cannot use the varargs syntax in this case as it's not a method parameter.
Depending on what you're using the Function type for, you may not even need it at all and you can just work with your methods as they are without having to reference them through functional interfaces.
As an alternative you can define your own functional interface like this:
#FunctionalInterface
public interface MyFunctionalInterface<T, R> {
R apply(T... args);
}
then your declaration becomes:
MyFunctionalInterface<String, String> doWork = a -> doSomethingWithArray(a);
and calling doWork can now be:
String one = doWork.apply("one");
String two = doWork.apply("one","two");
String three = doWork.apply("one","two","three");
...
...
note - the functional interface name is just a placeholder and can be improved to be consistent with the Java naming convention for functional interfaces e.g. VarArgFunction or something of that ilk.

Because arrays and varargs are override-equivalent, the following is possible:
#FunctionalInterface
interface VarArgsFunction<T, U> extends Function<T[], U> {
#Override
U apply(T... args);
}
// elsewhere
VarArgsFunction<String, String> toString =
args -> Arrays.toString(args);
String str = toString.apply("a", "b", "c");
// and we could pass it to somewhere expecting
// a Function<String[], String>
That said, this has a pitfall having to do with invoking the method generically. The following throws a ClassCastException:
static void invokeApply() {
VarArgsFunction<Double, List<Double>> fn =
Arrays::asList;
List<Double> list = invokeApply(fn, 1.0, 2.0, 3.0);
}
static <T, U> U invokeApply(VarArgsFunction<T, U> fn,
T arg0, T arg1, T arg2) {
return fn.apply(arg0, arg1, arg2); // throws an exception
}
(Example in action.)
This happens because of type erasure: invoking the apply method generically creates an array whose component type is the erasure of the type variable T. In the above example, since the erasure of the type variable T is Object, it creates and passes an Object[] array to the apply method which is expecting a Double[].
Overriding the apply method with generic varargs (and more generally writing any generic varargs method) will generate a warning and that's why. (The warning is mandated in 8.4.1 of the JLS.)
Because of that, I don't actually recommend using this. I've posted it because, well, it's interesting, it does work in simpler cases and I wanted to explain why it probably shouldn't be used.

One safe way to target a varargs method to a strongly typed Function is by using a technique called currying.
For example, if you need to target your varargs method with 3 arguments, you could do it as follows:
Function<String, Function<String, Function<String, String>>> doWork =
a1 -> a2 -> a3 -> doSomethingWithArray(a1, a2, a3);
Then, wherever you need to call the function:
String result = doWork.apply("a").apply("b").apply("c");
This technique works to target not only varargs methods, but also any method with any number of arguments of different types.
If you already have an array with the arguments, just use a Function<String[], String>:
Function<String[], String> doWork = a -> doSomethingWithArray(a);
And then:
String[] args = {"a", "b", "c"};
String result = doWork.apply(args);
So, whenever you have a fixed number of arguments, use currying. And whenever you have dynamic arguments (represented by an array), use this last approach.

Short answer
This doesn't seem possible. Function interface has only four methods, and none of those methods takes vararg arguments.
Extend Function interface?
Doesn't work either. Since arrays are somewhat strange low-level constructs in Java, they do not work well with generic types because of type erasure. In particular, it is not possible to create an array of generic type without contaminating your entire codebase with Class<X>-reflection-thingies. Therefore, it's not even feasible to extend the Function<X, Y> interface with a default method which takes varargs and redirects to apply.
Syntax for array creation, helper methods
If you statically know the type of the arguments, then the best thing you can do is to use the inline syntax for array creation:
myFunction.apply(new KnownType[]{x, y, z});
instead of the varargs, which you want:
myFunction.apply(x, y, z); // doesn't work this way
If this is too long, you could define a helper function for creation of
arrays of KnownType from varargs:
// "known type array"
static KnownType[] kta(KnownType... xs) {
return xs;
}
and then use it as follows:
myFunction.apply(kta(x, y, z, w))
which would at least be somewhat easier to type and to read.
Nested methods, real varargs
If you really (I mean, really) want to pass arguments of known type to a black-box generic Function using the vararg-syntax, then you need something like nested methods. So, for example, if you want to have this:
myHigherOrderFunction(Function<X[], Y> blah) {
X x1 = ... // whatever
X x2 = ... // more `X`s
blah(x1, x2) // call to vararg, does not work like this!
}
you could use classes to emulate nested functions:
import java.util.function.*;
class FunctionToVararg {
public static double foo(Function<int[], Double> f) {
// suppose we REALLY want to use a vararg-version
// of `f` here, for example because we have to
// use it thousand times, and inline array
// syntax would be extremely annoying.
// We can use inner nested classes.
// All we really need is one method of the
// nested class, in this case.
class Helper {
// The inner usage takes array,
// but `fVararg` takes varargs!
double fVararg(int... xs) {
return f.apply(xs);
}
double solveTheActualProblem() {
// hundreds and hundreds of lines
// of code with dozens of invokations
// of `fVararg`, otherwise it won't pay off
// ...
double blah = fVararg(40, 41, 43, 44);
return blah;
}
}
return (new Helper()).solveTheActualProblem();
}
public static void main(String[] args) {
Function<int[], Double> example = ints -> {
double d = 0.0;
for (int i: ints) d += i;
return d / ints.length;
};
System.out.println(foo(example)); // should give `42`
}
}
As you see, that's a lot of pain. Is it really worth it?
Conclusion
Overall, this seems to be an idea which would be extremely painful to implement in Java, no matter what you do. At least I don't see any simple solutions. To be honest, I also don't see where it would be really necessary (maybe it's just me vs. the BLUB-paradox).

Unfortunately, adding a method to intercede and do the translation for you was all I could come up with.
public class FunctionalTest {
public static void main( String[] args ) {
kludge( "a","b","c" );
}
private static Function<String[],PrintStream> ref = a -> System.out.printf( "", a );
public static void kludge( String... y ) {
ref.apply( y );
}
}

Related

Passing generic ToIntFunction to method in one line

Suppose I have a several Lists of different objects and I want to map these Objects to an int value (Such as returning the length of a String) so I can perform operations in a Stream. So I create a method such as:
public <T> int foo(List<T> list, ToIntFunction<T> toInt) {
return list.stream().mapToInt(toInt).max().orElse(Integer.MIN_VALUE);
}
(Note: max may be some other terminal operation)
Then I want to pass a ToIntFunction to it. I can do:
ToIntFunction<String> length = e -> e.length();
int bar = foo(list, length);
However I would have to write out the ToIntFunction every time I called the method.
Is there a way to just do something like:
foo(list, new ToIntFunction<String>(e -> e.length()) );
//Obviously ToIntFunction is an interface and can't be instantiated
Or is it necessary to do it on two lines with a named variable?
Just pass it as an inline lambda like so,
foo(Arrays.asList("test"), e -> e.length());
Or else here's the more readable method reference based approach,
foo(Arrays.asList("test"), String::length);
The trick here is that the ToIntFunction<T> is a single abstract method interface and the language allows you to create instances of these interfaces using lambda expressions.
Above lambda expression is just a syntactic sugar which substitutes more verbose anonymous inner class. Here's that pre-Java8 approach.
int bar = foo(Arrays.asList("test"), new ToIntFunction<String>() {
#Override
public int applyAsInt(String value) {
return value.length();
}
});

Calling a function without doing a new

I wrote a sort function and class in Java:
public class MiscellaneousUtilities {
/**
* Changes a list of "First Last" to "Last, First" and "First Middle Last" to "Last, First Middle", etc.
*/
public static Function<String, String> ToLastFirstFunction = new Function<String, String>() {
#Override
public String apply(String nm) {
String[] nmarr = nm.split(" ");
int last = nmarr.length - 1;
String res = nmarr[last];
if (last > 0) {
res += ",";
}
for (int i = 0; i < last; i++) {
res += " " + nmarr[i];
}
return res;
};
};
}
When I want to use it I can't just say MiscellaneousFunctions.ToFirstLastFunction()
I have to do a new MiscellaneousFunctions().ToFirstLastFunction;
I tried putting static in front of the class declaration but it allows only public, final and abstract. Looking at the Math class if I want to use Math.min() I don't have to do a new Math().min(). Math is also defined as a class that does not have static in front of it, and min() does as does ToFirstLastFunction, so I don't understand the difference.
That's because you have to call that function with an apply like this:
MiscellaneousFunctions.ToFirstLastFunction.apply("yourstring");
You can add an other static function as a shorthand though:
public static String toFirstLast(String str) {
return ToLastFirstFunction.apply(str);
}
The main difference between Math.min and your solution that Math.min is a regular static method while you have a Function object and those can be called with apply.
Math.min() is a a method not a function, declared like this in Math.class:
public int min(int a, int b) {
...
}
... and it is methods like this that you can invoke directly as in int x = Math.min(3,2).
You have created a public static class variable called ToLastFirstFunction -- that's not something you can call like a method. But you can do things with it using the methods in the java.util.function.Function interface -- the simplest being apply():
String out = MiscellaneousFunctions.toFirstLastFunction.apply("John Doe");
(I changed the capitalisation of your identifier -- find out about Java capitalisation conventions)
It is not the case that you can call your public static Function<...> using new MiscellaneousFunctions().toFirstLastFunction("John Doe") -- I'm not sure why you thought it was so.
You can do new MiscellanousFunctions().toFirstLastFunction.apply("John Doe") -- but your compiler should warn you about accessing a static variable via an instance. MiscellanousFunctions.toFirstLastFunction.apply() is the right way.
So the short answer to your question is: if you want to invoke it that way, write it as a method.
But if that's the case, why would you define an operation as a function, rather than a method?
Well, functions have the benefit that, unlike methods(*), they are objects -- so you can pass them around, put them in collections, assign them to variables. And they have methods like compose() and andThen() which return a new function that combines this function with another.
So you can do things like:
Map<String,Function<String,String> nameTranslationStrategies = new HashMap<>();
nameTranslationStrategies.put(
"no change", x -> x);
nameTranslationStrategies.put(
"to first-last",
MiscellaneousFunctions.toFirstLastFunction);
nameTranslationStrategies.put(
"capitalised first-last",
MiscellaneousFunctions.toFirstLastFunction
.andThen( s -> s.toUpperCase());
...
String nameTranslationOption = config.getProperty("nameTranslationOption");
String name = nameTranslationStrategies
.get(nameTranslationOption)
.apply(inputString);
Java programmers managed for decades without this feature -- functions didn't exist until Java 8. But you can do lots of neat things with them.
Even so, this isn't a reason to write your code as a Function bound to a static variable, since you can access ordinary methods as functions using the :: syntax:
Function<Double,Double> logarithm = Math::log;
double x = logarithm.apply(2.0);
Note also, that you've used a long-winded syntax to define your function:
public static Function<String, String> slimify = new Function<String, String>() {
#Override
public String apply(String s) {
return "slim says " + s;
}
}
... can be written as:
public static Function<String,String> slimify = s -> {
return "slim says " + s;
}
... or even (since this one's a one-liner)
public static Function<String,String> slimify = s -> "slim says " + s;
It's good to know the long-winded way, because it shows how functions work behind the scenes. But in real world code, the shorter form is the way to go, as it is more expressive: the intent of the code isn't hidden by clutter. This is such a quick and easy way of expressing a function, that people often use them in-line rather than assign them to a variable -- as I have done in the map example above.
(*) I said that methods are not objects. This isn't strictly true -- partly because you can get one as an object using ::, but also because you can use Java's Reflection API to access classes and methods as objects. But you don't want to use Reflection, unless you really know you need to.
Math.min() is a public static method called min, your Function is a Function object, it's not a method. Your object has a method apply and you have to use that method for what you want to achieve, like this:
MiscellaneousFunctions.ToFirstLastFunction.apply(something)

Can I have function types in Java's Enum like Swift?

Is it possible to write an equivalent code in Java for the following swift code? In fact, I want to know if it's possible to have a case of functions inside Java's enum (X, Y in MyEnum)
enum MyEnum{
case X((Int) -> String)
case Y((Double) -> Int)
}
No, you can't; at least, not if you want the differing types to be available when you use the enum. All enum values have to have the same type.
When you want "enum" values to have heterogenous types, you could use a class with static final fields:
final class MyHeterogeneousEnum {
private MyHeterogeneousEnum() {} // Not instantiable.
static final Function<Integer, String> X = ...;
static final Function<Double, Integer> Y = ...;
}
which allows you to use the values with their full type information:
String s = MyHeterogeneousEnum.X.apply(123);
Integer i = MyHeterogeneousEnum.Y.apply(999.0);
Of course, you don't have useful methods like name(), or values() to iterate over the constants in this class, nor is it inherently serializable. You can make implement these yourself - but for values() you have to use wildcards in the return type, in order that all values can be returned:
static Iterable<Function<?, ?>> values() {
return Collections.unmodifiableList(Arrays.asList(X, Y));
}
However, note that a Function with a wildcard input type parameter is pretty much useless: you can't actually pass anything into it (other than null); so the values() method has limited utility.
It is possible (technically), but it might not be that useful, as creating a simple class, that consumes a Function instance.
As you might already know, in Java, the enums represent one or more constants of the same type, which could have their own properties - this include java.util.Function instances. However, these Function instances cannot be passed dynamically at Runtime, but should be rather set at compile time, so that the constant is created.
Of course, you could make each enum constant have a different typed Function, by just creating the enum's constructor Generic:
enum MyEnum {
X((String x) -> "Hello"), Y((Double d) -> 1);
Function<?, ?> function;
MyEnum(Function<?, ?> function) {
this.function = function;
}
}
This, however, is not quite useful (although it compiles just fine). The Function in X doesn't use it's String parameter and returns a fixed value. So does the one in Y.
I'd rather introduce two separate instances of the same class:
class Instance<T, U> {
private Function<T, U> function;
public Instance(Function<T, U> function) {
this.function = function;
}
}
This will allow you to dynamically pass a Function instance, instead of setting it at compile-time.
Yes for sure you can, in java enums can be more that just constants... every one of it values can be an anonymous class (take a look to TimeUnit.class for example)
now, you can do somthing like:
interface IFunction {
double getY(double x);
}
enum Function implements IFunction {
LINE {
#Override
public double getY(double x) {
return x;
}
},
SINE {
#Override
public double getY(double x) {
return Math.sin(x);
}
}
}
and then the implementation
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
System.out.println(Function.LINE.getY(i));
System.out.println(Function.SINE.getY(i));
}
}

How to transform an array to a list of args for method invocation in Java

I have been puzzled by this problem for two days. I have a list of testN methods in the Class Test, and i will add more test* methods for this class. The sample code is shown below
public class Test {
public void test1(String a, int b, boolean c){
System.out.println("a="+a+" "+b+ " c="+c);
}
public void test3(Test test){
System.out.println(test.toString());
}
public void run(Object... objs){
//First way...
if(objs.length>=3){
test1((String)objs[0], (int)objs[1], (boolean)objs[2]);
}else if(objs.length <3 ){
test3((Test)objs[0]);
}
//Second way?
MethodType type1 = MethodType.methodType(void.class, String.class, int.class, boolean.class);
if(objs.length>=3){
//How to tranform first 3 elements of objs to a list (String, int, boolean)
Object[] t = Arrays.copyOfRange(objs, 0, type1.parameterCount());
test1(???);
}
MethodType type3 = MethodType.methodType(void.class, Test.class);
if(objs.length < 3 ){
}
}
public static void main(String[] args){
Test test = new Test();
test.run("String", 3, false, 5,7);
test.run(test,1);
}
}
the method run(Object... objs) is the main entry for this class, and it accepts a list of var args. Inside of method run, it invokes different test* method according to the objs' length (objs is recognized as array).
The problem for me is that how can i pass the Object[] t in the second way as a list of var args for method test1? The first way is handle-write which is not practical when more test* methods are added. The Object[] t is array and it is one object while test1 requires three parameters. I am seeking a way that can transform an array into a list of args for method invocation.
You need to use reflection. First, get your Test.class — that's easy, it's just Test.class. Next, get your method, this can be done either by knowing the types from your arguments (via .getClass() on each argument and the .getMethod(…) method of Class or by searching the array returned by getMethods(). Both will give you a Method object to work with. Finally, you can call the method with method.invoke(this, objs);.
Edit: Regarding your comment, there is no List of parameters. At least not as in java.util.List. The JVM indeed places the parameters on the stack (and is free to do so in any conceivable way; heck even the stack will in many cases be optimized away into registers).
So the problem is, you'd need to a) know the VM type of the object (which could be any of int, long, float, double, or ref) and b) the position of the object. Then you could do something similar by creating a synthetic bytecode sequence (note that while this would yield valid JVM bytecode, there is no valid Java code that does this unless you count custom class loaders). Otherwise, no, there is no way in Java to create an 'argument list'.

How to negate a method reference predicate

In Java 8, you can use a method reference to filter a stream, for example:
Stream<String> s = ...;
long emptyStrings = s.filter(String::isEmpty).count();
Is there a way to create a method reference that is the negation of an existing one, i.e. something like:
long nonEmptyStrings = s.filter(not(String::isEmpty)).count();
I could create the not method like below but I was wondering if the JDK offered something similar.
static <T> Predicate<T> not(Predicate<T> p) { return o -> !p.test(o); }
Predicate.not( … )
java-11 offers a new method Predicate#not
So you can negate the method reference:
Stream<String> s = ...;
long nonEmptyStrings = s.filter(Predicate.not(String::isEmpty)).count();
I'm planning to static import the following to allow for the method reference to be used inline:
public static <T> Predicate<T> not(Predicate<T> t) {
return t.negate();
}
e.g.
Stream<String> s = ...;
long nonEmptyStrings = s.filter(not(String::isEmpty)).count();
Update: Starting from Java-11, the JDK offers a similar solution built-in as well.
There is a way to compose a method reference that is the opposite of a current method reference. See #vlasec's answer below that shows how by explicitly casting the method reference to a Predicate and then converting it using the negate function. That is one way among a few other not too troublesome ways to do it.
The opposite of this:
Stream<String> s = ...;
int emptyStrings = s.filter(String::isEmpty).count();
is this:
Stream<String> s = ...;
int notEmptyStrings = s.filter(((Predicate<String>) String::isEmpty).negate()).count()
or this:
Stream<String> s = ...;
int notEmptyStrings = s.filter( it -> !it.isEmpty() ).count();
Personally, I prefer the later technique because I find it clearer to read it -> !it.isEmpty() than a long verbose explicit cast and then negate.
One could also make a predicate and reuse it:
Predicate<String> notEmpty = (String it) -> !it.isEmpty();
Stream<String> s = ...;
int notEmptyStrings = s.filter(notEmpty).count();
Or, if having a collection or array, just use a for-loop which is simple, has less overhead, and *might be **faster:
int notEmpty = 0;
for(String s : list) if(!s.isEmpty()) notEmpty++;
*If you want to know what is faster, then use JMH http://openjdk.java.net/projects/code-tools/jmh, and avoid hand benchmark code unless it avoids all JVM optimizations — see Java 8: performance of Streams vs Collections
**I am getting flak for suggesting that the for-loop technique is faster. It eliminates a stream creation, it eliminates using another method call (negative function for predicate), and it eliminates a temporary accumulator list/counter. So a few things that are saved by the last construct that might make it faster.
I do think it is simpler and nicer though, even if not faster. If the job calls for a hammer and a nail, don't bring in a chainsaw and glue! I know some of you take issue with that.
wish-list: I would like to see Java Stream functions evolve a bit now that Java users are more familiar with them. For example, the 'count' method in Stream could accept a Predicate so that this can be done directly like this:
Stream<String> s = ...;
int notEmptyStrings = s.count(it -> !it.isEmpty());
or
List<String> list = ...;
int notEmptyStrings = lists.count(it -> !it.isEmpty());
Predicate has methods and, or and negate.
However, String::isEmpty is not a Predicate, it's just a String -> Boolean lambda and it could still become anything, e.g. Function<String, Boolean>. Type inference is what needs to happen first. The filter method infers type implicitly. But if you negate it before passing it as an argument, it no longer happens. As #axtavt mentioned, explicit inference can be used as an ugly way:
s.filter(((Predicate<String>) String::isEmpty).negate()).count()
There are other ways advised in other answers, with static not method and lambda most likely being the best ideas. This concludes the tl;dr section.
However, if you want some deeper understanding of lambda type inference, I'd like to explain it a bit more to depth, using examples. Look at these and try to figure out what happens:
Object obj1 = String::isEmpty;
Predicate<String> p1 = s -> s.isEmpty();
Function<String, Boolean> f1 = String::isEmpty;
Object obj2 = p1;
Function<String, Boolean> f2 = (Function<String, Boolean>) obj2;
Function<String, Boolean> f3 = p1::test;
Predicate<Integer> p2 = s -> s.isEmpty();
Predicate<Integer> p3 = String::isEmpty;
obj1 doesn't compile - lambdas need to infer a functional interface (= with one abstract method)
p1 and f1 work just fine, each inferring a different type
obj2 casts a Predicate to Object - silly but valid
f2 fails at runtime - you cannot cast Predicate to Function, it's no longer about inference
f3 works - you call the predicate's method test that is defined by its lambda
p2 doesn't compile - Integer doesn't have isEmpty method
p3 doesn't compile either - there is no String::isEmpty static method with Integer argument
Building on other's answers and personal experience:
Predicate<String> blank = String::isEmpty;
content.stream()
.filter(blank.negate())
Another option is to utilize lambda casting in non-ambiguous contexts into one class:
public static class Lambdas {
public static <T> Predicate<T> as(Predicate<T> predicate){
return predicate;
}
public static <T> Consumer<T> as(Consumer<T> consumer){
return consumer;
}
public static <T> Supplier<T> as(Supplier<T> supplier){
return supplier;
}
public static <T, R> Function<T, R> as(Function<T, R> function){
return function;
}
}
... and then static import the utility class:
stream.filter(as(String::isEmpty).negate())
Shouldn't Predicate#negate be what you are looking for?
In this case u could use the org.apache.commons.lang3.StringUtilsand do
int nonEmptyStrings = s.filter(StringUtils::isNotEmpty).count();
I have written a complete utility class (inspired by Askar's proposal) that can take Java 8 lambda expression and turn them (if applicable) into any typed standard Java 8 lambda defined in the package java.util.function. You can for example do:
asPredicate(String::isEmpty).negate()
asBiPredicate(String::equals).negate()
Because there would be numerous ambiguities if all the static methods would be named just as(), I opted to call the method "as" followed by the returned type. This gives us full control of the lambda interpretation. Below is the first part of the (somewhat large) utility class revealing the pattern used.
Have a look at the complete class here (at gist).
public class FunctionCastUtil {
public static <T, U> BiConsumer<T, U> asBiConsumer(BiConsumer<T, U> biConsumer) {
return biConsumer;
}
public static <T, U, R> BiFunction<T, U, R> asBiFunction(BiFunction<T, U, R> biFunction) {
return biFunction;
}
public static <T> BinaryOperator<T> asBinaryOperator(BinaryOperator<T> binaryOperator) {
return binaryOperator;
}
... and so on...
}
You can use Predicates from Eclipse Collections
MutableList<String> strings = Lists.mutable.empty();
int nonEmptyStrings = strings.count(Predicates.not(String::isEmpty));
If you can't change the strings from List:
List<String> strings = new ArrayList<>();
int nonEmptyStrings = ListAdapter.adapt(strings).count(Predicates.not(String::isEmpty));
If you only need a negation of String.isEmpty() you can also use StringPredicates.notEmpty().
Note: I am a contributor to Eclipse Collections.
You can accomplish this as long emptyStrings = s.filter(s->!s.isEmpty()).count();
Tip: to negate a collection.stream().anyMatch(...), one can use collection.stream().noneMatch(...)
If you're using Spring Boot (2.0.0+) you can use:
import org.springframework.util.StringUtils;
...
.filter(StringUtils::hasLength)
...
Which does:
return (str != null && !str.isEmpty());
So it will have the required negation effect for isEmpty

Categories