Calling a function without doing a new - java

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)

Related

varargs as input parameter to a function in java 8

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 );
}
}

How can I pass two types of unlimited variables [duplicate]

Is there any way in Java to create a method, which is expecting two different varargs?
I know, with the same object kind it isn't possible because the compiler doesn't know where to start or to end. But why it also isn't possible with two different Object types?
For example:
public void doSomething(String... s, int... i){
//...
//...
}
Is there any way to create a method like this?
Thank you!
Only one vararg, sorry. But using asList() makes it almost as convenient:
public void myMethod(List<Integer> args1, List<Integer> args2) {
...
}
-----------
import static java.util.Arrays.asList;
myMethod(asList(1,2,3), asList(4,5,6));
In Java, only one varargs argument is allowed and it must be the last parameter of the signature.
But all it does it convert it to an array anyway, so you should just make your two parameters explicit arrays:
public void doSomething(String[] s, int[] i){
A possible API design in which the calling code looks like
doSomething("a", "b").with(1,2);
through "fluent" API
public Intermediary doSomething(String... strings)
{
return new Intermediary(strings);
}
class Intermediary
{
...
public void with(int... ints)
{
reallyDoSomething(strings, ints);
}
}
void reallyDoSomething(String[] strings, int[] ints)
{
...
}
The danger is if the programmer forgot to call with(...)
doSomething("a", "b"); // nothing is done
Maybe this is a little better
with("a", "b").and(1, 2).doSomething();
Only one vararg is allowed. This is because multiple vararg arguments are ambiguous. For example, what if you passed in two varargs of the same class?
public void doSomething(String...args1, String...args2);
Where does args1 end and args2 begin? Or how about something more confusing here.
class SuperClass{}
class ChildClass extends SuperClass{}
public void doSomething(SuperClass...args1, ChildClass...args2);
ChildClass extends SuperClass, and so is can legally exist in args1, or args2. This confusion is why only one varargs is allowed.
varargs must also appear at the end of a method declaration.
Just declare the specific type instead as 2 arrays.
Although this kind of thing is occasionally useful, usually if you find that you are hitting a restriction in Java you could probably redesign something and come out much better. Here are some possible other ways to look at it...
If the two lists are related at all you probably want to create a wrapper class for the two different lists and pass in the wrapper. Wrappers around collections are almost always a good idea--they give you a place to add code that relates to the collection.
If this is a way to initialize data, parse it from a string. For instance, "abc, 123:def, 456:jhi,789" is almost embarassingly easy to split up with 2 split statements and a loop (2-3 lines of code). You can even make a little custom parser class that parses a string like that into a structure you feed into your method.
Hmm--honestly asside from initializing data I don't even know why you'd want to do this anyway, any other case and I expect you'd be passing in 2 collections and wouldn't be interested in varags at all.
You can do something like this, then you can cast and add additional logic inside that method.
public void doSomething(Object... stringOrIntValues) {
...
...
}
And use this method like so:
doSomething(stringValue1, stringValue2, intValue1, intValue2,
intValue3);
This is an old thread, but I thought this would be helpful regardless.
The solution I found isn't very neat but it works. I created a separate class to handle the heavy lifting. It only has the two variables I needed and their getters. The constructor handles the set methods on its own.
I needed to pass direction objects and a respective Data object. This also solves the possible problem of uneven data pairs, but that is probably only for my usage needs.
public class DataDirectionPair{
Data dat;
Directions dir;
public DataDirectionPair(Data dat, Directions dir) {
super();
this.dat = dat;
this.dir = dir;
}
/**
* #return the node
*/
public Node getNode() {
return node;
}
/**
* #return the direction
*/
public Directions getDir() {
return dir;
}
}
I would then just pass this class as the vararg for the method
public void method(DataDirectionPair... ndPair){
for(DataDirectionPair temp : ndPair){
this.node = temp.getNode();
this.direction = temp.getDir();
//or use it however you want
}
}
It is not possible because the Java Language Specification says so (see 8.4.1. Formal Parameters):
The last formal parameter of a method or constructor is special: it
may be a variable arity parameter, indicated by an ellipsis
following the type.
Note that the ellipsis (...) is a token unto itself (§3.11). It is possible to put whitespace between it and the type, but this is
discouraged as a matter of style.
If the last formal parameter is a variable arity parameter, the method
is a variable arity method. Otherwise, it is a fixed arity method.
As to why only one and only the last parameter, that would be a guess, but probably because allowing that could lead to undecidable or ambiguous problems (eg consider what happens with method(String... strings, Object... objects)), and only allowing non-intersecting types would lead to complications (eg considering refactorings where previously non-intersecting types suddenly are), lack of clarity when it does or does not work, and complexity for the compiler to decide when it is applicable or not.
I just read another question about this "pattern", but it is already removed, so I would like to propose a different approach to this problem, as I didn't see here this solution.
Instead to force the developer to wrapping the inputs parameter on List or Array, it will be useful to use a "curry" approach, or better the builder pattern.
Consider the following code:
/**
* Just a trivial implementation
*/
public class JavaWithCurry {
private List<Integer> numbers = new ArrayList<Integer>();
private List<String> strings = new ArrayList<String>();
public JavaWithCurry doSomething(int n) {
numbers.add(n);
return this;
}
public JavaWithCurry doSomething(String s) {
strings.add(s);
return this;
}
public void result() {
int sum = -1;
for (int n : numbers) {
sum += n;
}
StringBuilder out = new StringBuilder();
for (String s : strings) {
out.append(s).append(" ");
}
System.out.println(out.toString() + sum);
}
public static void main(String[] args) {
JavaWithCurry jwc = new JavaWithCurry();
jwc.doSomething(1)
.doSomething(2)
.doSomething(3)
.doSomething(4)
.doSomething(5)
.doSomething("a")
.doSomething("b")
.doSomething("c")
.result();
}
}
As you can see you in this way, you could add new elements of which type you need when you need.
All the implementation is wrapped.
If you are not going to be passing a large number of Strings most of the time for the first argument you could provide a bunch of overloads that take different numbers of Strings and wrap them in an array before calling a method that takes the array as the first argument.
public void doSomething(int... i){
doSomething(new String[0], i);
}
public void doSomething(String s, int... i){
doSomething(new String[]{ s }, i);
}
public void doSomething(String s1, String s2, int... i){
doSomething(new String[]{ s1, s2 }, i);
}
public void doSomething(String s1, String s2, String s3, int... i){
doSomething(new String[]{ s1, s2, s3 }, i);
}
public void doSomething(String[] s, int... i) {
// ...
// ...
}
follwing on Lemuel Adane (cant comment on the post, due to lack of rep :))
if you use
public void f(Object... args){}
then you may loop using How to determine an object's class (in Java)?
like for instance
{
int i = 0;
while(i< args.length && args[i] instanceof String){
System.out.println((String) args[i]);
i++ ;
}
int sum = 0;
while(i< args.length){
sum += (int) args[i];
i++ ;
}
System.out.println(sum);
}
or anything you intend to do.
You can convert your varargs to arrays
public void doSomething(String[] s, int[] i) {
...
}
then with some helper methods to convert your varargs to array like this:
public static int[] intsAsArray(int... ints) {
return ints;
}
public static <T> T[] asArray(T... ts) {
return ts;
}
Then you can use those helper methods to convert your vararged parameters.
doSomething(asArray("a", "b", "c", "d"), intsAsArray(1, 2, 3));

Deciding what method to call at runtime without using interfaces for context (no Java8 features)

The title can easily be misunderstood, but it boils down to that I most likely require a design-pattern to eliminate redundant code. To make my question as clear as possible I made a code example instead of writing a vague explanation.
Basically, I have the following functions:
getValue1(), getValue2(), getValue3(), ... , getValue12()
These functions could look as follows (though all differ slightly from each other and are not editable by means of making them implement an interface for a strategy pattern):
public int getValue1()
{
return 1 + 2;
}
Next we have a secondary class myClass which requires the values returned by the getValue() functions. A function from myClass would then look as follows (each differ in the fact that they make use of a different getValue() function):
public int getMyValues1()
{
int[] values = new int[10];
for (int i = 0; i < 10; i++) {
int[i] = getValue1() // NOTE: getValueX() may output differently each time.
}
}
We have arrived at our problem.
If we would make a getMyValues() function for each respective getValue(), we would have to copy and then paste the same code several times.
This goes against everything OOP languages stand for - that's why I require your help.
Any suggestion is much appreciated!
EDIT:
I reopened the question, because I didn't have Java 8 supported on the IDE I am to use.
Basically I have the following setup:
getValueClass
getValue1()
getValue2()
etc.
myClass
getMyValues1()
getMyValues2()
etc.
implemetingClass
private myClass mc = new MyClass()
main()
getLowestValue(int[] values)
And so main() could look as follows - if i'd wish to output the lowest value:
public static void main(String[] args)
{
...
System.out.print(getLowestValue(mc.getMyValues1()));
...
}
This edit goes to show that a strategy pattern isn't viable, since I have my functions in one class.
Hopefully this clears up any confusion and I really hope you guys can help me solve this issue!
Assuming these methods are public, then in Java 8, you should be able to use a functional interface (in this trivial example it would be a java.util.function.IntSupplier) and pass a reference to these methods as a lambda expression.
Something like (compilation not tested):
public int[] getMyValues(IntSupplier supplier) {
int[] values = new int[10];
for (int i = 0; i < 10; i++) {
int[i] = supplier.getAsInt()
}
return values;
}
Called using:
int[] values = someobject.getMyValues(someobject::getValues1)
This is more or less using those methods as strategies without the need to make an actual interface and multiple implementations: the strategy interface is the functional interface itself and the method references generate the implementation.
EDIT: if you can't use Java 8, then you can just define your own interface with just 1 method that returns the int. The calling just becomes longer because of the lack of support for method references:
int[] values = someobject.getMyValues(new MyIntProducer() {
public int getValue() { return someobject.getValues1(); };
}
Note that the someobject local variable will need to be made final for this to work.
You can use reflection. I don't recommend doing it this way but there is a time place for this type of thing.
import java.util.Map;
import java.util.HashMap;
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
public class ReflectiveGetter {
private final Object theObject;
private final String methodPattern;
private final Map<Integer, Method> methodsByIndex = new HashMap<Integer, Method>();
public ReflectiveGetter(Object theObject, String methodPattern) {
this.theObject = theObject;
this.methodPattern = methodPattern;
String patternToMatch = methodPattern + "\\d+";
for(Method m : theObject.getClass().getMethods()) {
String name = m.getName();
if(name.matches(patternToMatch)) {
m.setAccessible(true);
int i = Integer.parseInt(name.substring(methodPattern.length()));
methodsByIndex.put(i, m);
}
}
}
public int getValue(int index)
throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
Method m = methodsByIndex.get(index);
if(m != null) {
return (Integer)m.invoke(theObject);
}
throw new NoSuchMethodException(methodPattern + index);
}
}
Usage is:
ReflectiveGetter rg = new ReflectiveGetter(theValueObject, "getValue");
System.out.println(rg.getValue(1)); // prints as if theValueObject.getValue1()
Reflection is clumsy and you should not use it if you do not know what you are doing or there are more convenient options.
For example, perhaps the value class should be using a Map to begin with.

Java - Inline definition of comparator for Collection.max

I am looking for a Java equivalent for python snippet
max_valued_key = max(str_to_double_map.keys(), key=lambda x: str_to_double_map[x])
I want to something standard like Collections.max
Is there a way to do this with inline definition of Comparator since I don't want to write one more class for every other comparator.
I tried following code unsuccessfully
depScores = foo();
String dep = Collections.max(depScores.keySet(), new Comparator<String>() {
#Override
public int compare(String o1, String o2) {
return depScores.get(o1).compareTo(depScores.get(o2));
}
});
depScores variable is not readable from comparator.
Looks like in java inner class cannot access non-final variable from outside!
Thanks in advance!
Just declare depScores as a final variable. If for some reason you can't, create a second (final) variable that points to it.
Local classes can capture variables only if they are final.
As a (very) late addendum, it is trivial to create a custom Comparator from a lambda in Java 8:
String dep = Collections.max(
depScores.keySet(),
Comparator.comparing(k -> depScores.get(k))
);
You can get even more terse by replacing the lambda k -> depScores.get(k) with the method reference depScores::get.
The rules for capturing local variables like depScore are a little more flexible for lambdas than inner classes: captured variables need only be effectively final. In other words, they must be assigned exactly once, though they needn't be explicitly marked final.
What you want is (will be) possible with Java 8:
Map<String,Double> map…
String maxKey=Collections.max(map.keySet(), (x,y)->Double.compare(map.get(x),map.get(y)));
or even shorter
String maxKey = Collections.max(map.keySet(), Comparator.comparingDouble(map::get));
For previous Java version you have to use:
String maxKey=Collections.max(map.keySet(), new Comparator<String>(){
public int compare(String x, String y) {
return Double.compare(map.get(x),map.get(y));
}
});
Problems with map not being final can be circumvented by assigning it to a final variable right before the invocation:
final Map<String,Double> fmap=map;
String maxKey=Collections.max(map.keySet(), new Comparator<String>(){
public int compare(String x, String y) {
return Double.compare(fmap.get(x),fmap.get(y));
}
});
But I think even more straightforward and more efficient will be the following helper method as it does not require any hash lookups:
static <K,V extends Comparable<V>> K keyForHighestValue(Map<K,V> map) {
V maxValue=Collections.max(map.values());
for(Map.Entry<K,V> e:map.entrySet()) {
if(e.getValue()==maxValue) return e.getKey();
}
throw new ConcurrentModificationException();
}

Calling another function by adding it to a parameter

I was wondering if it's possible to call another function just by adding the function name to the parameter. So for instance I want to make a script with 4 parts. Each part requires input (I am using a scanner, dont ask why :P its the assignment) and then needs to pass it to another script for e.g. calculations and stuff.
I start of with this:
static int intKiezer(String returnFunctie, String text) {
Scanner vrager = new Scanner(System.in);
while (true) {
System.out.println(text);
int intGekozen = vrager.nextInt();
if (vrager.hasNextInt()) {
returnFunctie(intGekozen);
}
else {
vrager.next();
System.out.println("Verkeerde invoer!");
}
}
As you see I am trying to push the obtained value to another function by trying to call it (returnFunctie(intgekozen)). It should be calling returnFunctie with intgekozen as parameter. But its not working
I would be calling the function like this: intKiezer(sphereCalculations, "What radius do you want to have?"). So the answer from the input, if its correct should be passed to another function called sphereCalculations
Here is an idea.
Define an interface that has a method that does whatever calculation you want to perform. For example:
interface Algorithm {
int execute(int value);
}
Then define one or more classes that implement the interface and do whatever calculations you want them to do. For example:
class MultiplyByTwo implements Algorithm {
public int execute(int value) {
return value * 2;
}
}
class AddThree implements Algorithm {
public int execute(int value) {
return value + 3;
}
}
Then, write your method so that it accepts an Algorithm as a parameter. Execute the algorithm with the desired value.
static int intKiezer(Algorithm algo, String text) {
// ...
return algo.execute(intGekozen);
}
Call your method by passing in an instance of one of the implementation classes of interface Algorithm.
int result = intKiezer(new MultiplyByTwo(), "Some question");
System.out.println("Result: " + result);
As #Jesper said, it is possible with reflection, and probably only with reflection. Reflection is the process in which an object can analyze itself and iterate through it's members (attributes and methods). In your case, it seems you are looking for a method.
By the looks of your code, it seems like what you want is, in fact, passing a function object to your code, where a parameter could be applied. This isn't possible in Java. Something similar will be possible in Java 8 with the addition of closures. You could do that in Groovy, by passing a Closure as a parameter, or other language with support for closure or functions.
You can get near what you want by defining an abstract class/interface, passing an instance of it to your method, and then calling a method passing the parameter to it, like:
interface Function <T> {
public Integer call(T t);
}
public class TestFunction {
static int intKiezer(Function<Integer> returnFunctie, String text)
{
int a = 10;
System.out.println(text);
return returnFunctie.call(a);
}
public static void main(String[] args)
{
Function<Integer> function = new Function<Integer>() {
public Integer call(Integer t) { return t * 2; }
};
System.out.println( intKiezer(function, "Applying 10 on function") );
}
}
If your intention is to call a method, then you are better using some reflection library. Apache Common's MethodUtil comes to mind. I think this your man:
invokeMethod(Object object, String methodName, Object arg)
Invoke a named method whose parameter type matches the object type.

Categories