Assign proper function to the object of a class - java

I have a clas called as MyFunctions that defines different functions func1, func2, etc. Also I have a class Process that stores the function name assigned to the object of this class:
Process p1 = new Process();
String fName1 = "func1";
p1.setFunctionName(fName1);
Process p2 = new Process();
String fName2 = "func2";
p2.setFunctionName(fName2);
In order to run a proper function, I do the following:
MyFunctions f = new MyFunctions();
if (p.getFunctionName() == "func1") {
output = f.func1(inputdata);
} else if (p.getFunctionName() == "func2") {
output = f.func2(inputdata);
}
I´m not sure that this approach is efficient. Is there any other way to solve this task?
Another question: is it possible to do something like this in JAVA?:
String fName = p.getFunctionName();
output = f."+fName+"(input);

First, this approach is not exactly correct. Never use == to compare objects. Use equals() instead:
MyFunctions f = new MyFunctions();
if ("func1".equals(p.getFunctionName())) {
output = f.func1(inputdata);
} else if ("func2".equals(p.getFunctionName())) {
output = f.func2(inputdata);
}
Second, I'd suggest you to use enum instead.
public enum FunctionInvoker {
func1 {
public Object invoke(MyFunctions o, Object ... arg) {
o.func1(arg[0]);
}
},
func2 {
public Object invoke(MyFunctions o, Object ... arg) {
o.func2(arg[0], arg[1]);
}
},
}
Now the usage looks like:
String functionName = ...; // probably read from file, etc.
Object result = FunctionInvoker.valueOf(functionName).invoke(args);

Java's Reflection API will most likely be useful to you. It allows you (among other things) to find methods in classes at runtime (when you have for example the method name in a string) and call methods that way.
A simple example:
String inputdata = "Hello";
// Finds the method "func1" in class MyFunctions that takes a String argument
Method method = MyFunctions.class.getMethod("func1", String.class);
// Calls the method on a new MyFunctions object, passing in inputdata
// as the argument
Object result = method.invoke(new MyFunctions(), inputdata);
System.out.println("Return value: " + result);

If you have a determined set of functions, then use public static constants to declare the names of the functions.
Example:
public static String FUNCTION1 = "func1";
public static String FUNCTION2 = "func2";
For you second question, yes it is possible using java reflection.

You can use reflection to find the function to execute.
For instance:
f.getClass().getDeclaredMethod(p.getFunctionName).invoke();

I´m not sure that this approach is efficient. MyFunctions f = new MyFunctions();
if (p.getFunctionName() == "func1") {
No. AFAIK it will not work. You are comparing references of String instead of comparing it's content.
if (p.getFunctionName() == "func1")
use .equals instead of == to compare 2 strings.
is it possible to do something like this in JAVA? output = f."+fName+"(input);
You can use reflection in java to do what you want.

Use an enum to decouple:
public enum Function {
ONE {
public void call(Functions functions) {
functions.func1();
},
TWO {
...
};
public abstract void call(Functions functions);
}
An the process:
Process p1 = new Process(Function.ONE);
MyFunctions f = new MyFunctions();
p1.call(f);
Hope you got the idea :)

Related

Use the result set of a class method into another class method

i have a class A in which there is a method Method1, in Method1 i want to pass the "rs" to class B method. how can i do it? try different things but unsuccessful.
Note: I did not write the full method code just gave an scenario to find the solution from you.
public class A {
Resultset rs = null;
public void method1() {
this.rs = this.stmt.executeQuery(this.query);
// while (this.rs.next()) {
// int id = rs.getInt("node_Id");
// String name = rs.getString("node_Name");
// String par = rs.getString("node_Parent");
// int lvl = rs.getInt("node_Level");
// System.out.println(+id+" "+name+" "+par+" "+lvl);}
if (success == 0) {
this.conn.rollback();
} else {
System.out.println("rs" + rs);
this.conn.commit();
}
}
now i want to use the variables id,name,par,lvl in another class method like
following
public class B{
public void usage(){
//in here i want to get the varibles id,name,par,lvl
}
}
Right now, you made these variables to be local variables within method1() (which is by the way a really bad name for a method - always use names that mean something, even in examples).
Because of that, you can only pass them around, by well, passing then, such as
B someB instance = ... // however that gets created
while (this.rs.next()) {
int id = rs.getInt("node_Id");
someB.doSomethingWith(id);
That's it. But the better approach would be to have, say a class C that wraps around all the information you want to pass around.
Then instead of creating and passing the individual values, you would collect the required values, and use those to create an instance of your new C class. And then you pass that object to whatever method that is going to need it.

Make Object field into list using lambda

I'm new to java lambda expression so i don't know exactly if what i'm asking is possible. If not possible please suggest a better way if any.
I have an class Object such as:
class Loan {
private String customerId;
private Integer tenure;
private Double amount;
...
}
I need to convert this object into a list of string. The way I'm doing it right now is:
List<String> loanAsList = getListFromLoan(loan);
public List<String> getListFromLoan(Loan loan) {
List<String> loanAsList = new ArrayList<>();
loanAsList.add(loan.getCustomerId());
loanAsList.add(Integer.toString(loan.getTenure());
loanAsList.add(Double.toString(loan.getAmount());
}
Can this be done using a lambda expression?
Loan has many more fields I have only shown a few. I want an expression in which no matter the number of field I could get a List.
A lambda function is just a function. Could you do what you need with a regular method?
If you want to achieve what you say (a method that, no matter how many attributes your class has, adds them all to a list) you'll need to either do it manually and update it every time you add/remove an attribute or use reflection
Something like this:
Loan loan = ...
List<String> loanAsList = new ArrayList<>();
for (Field f : loan.getClass().getDeclaredFields()) {
field.setAccessible(true);
Object value = field.get(loan);
loanAsList.add(value.toString());
}
Object someObject = getItSomehow();
for (Field field : someObject.getClass().getDeclaredFields()) {
field.setAccessible(true); // You might want to set modifier to public first.
Object value = field.get(someObject);
if (value != null) {
System.out.println(field.getName() + "=" + value);
}
}
Lambda Expressions don't do magic in Java 8(well they do but not what you are expecting if I understood you right).
Look at lambda expression as an alternate to anonymous classes, with the advantage that you don't need to wrap it in a class for it implement a function(method in pre java 8 terms). Look up "Behaviour Parameterisation" for a better understanding.
Saying that you can use "Function" functional interface provided by jdk. Represents a function that accepts one argument and produces a result. So you can write a method
public List<String> getListOfAttributes(Loan loan, Function<Loan, List<String>> myFunction) {
return myFunction.apply(loan);
}
and then call this method
getListOfAttributes(loan, (loan) -> {
List<String> loanAsList = new ArrayList();
loanAsList.add(loan.getCustomerId());
loanAsList.add(Integer.toString(loan.getTenure());
loanAsList.add(Double.toString(loan.getAmount());
return loanAsList;
}
so because of "behaviour parameterisation" you can pass in different functionalities to get the different List.

How can I make a string of objects names in java

I would like to write a function that would enable me to do the following
inputs: variable number of objects of any type
output: a string that would be NameObj1=ValueObj1, ..., NameObjN=ValueObjN
All objects I would pass to the function would have a toString() method.
Example:
double x=1.1; int y=2; ClassA a
theFunction(x,y,a)
=> this would output "x=1.1, y=1, a=[whatever a.toString() output]"
Is that possible ?
here's something close:
you can write a var-arg function like so:
public static String describeArguments (Object... arguments) {
StringBuilder output = new StringBuilder();
int counter = 1;
for (Object argument : arguments) {
output.append("object #").append(counter++).append(": ").append(argument.toString());
}
return output.toString();
}
strictly speaking method arguments dont have names. you could retrieve the argument parameter name using reflection if the symbol tables werent stripped out #compile time, but its brutish and ugly.
There's no way of getting what you wrote to be the "name" of a variable, because the only way of referencing it, is by itself, and by value is not possible as well.
As mentioned in other answers and comments there is no "name of an object". But if the objects you are interested in are all fields of one class, you could write a function that uses reflection to access that objects fields and prints their names.
Take a look at the reflection tutorial. There is also an example that is very close to what you might have in mind.
You can create a map like
Map<String,Object> map= new HashMap<String,Object>();
map.put("x", 1.1);
map.put("y",2);
map.put("a", MyClass.class);
And call theFunction(map), where theFunction is:
public void theFunction(HashMap<String,Object> list) {
StringBuilder sb = new StringBuilder();
for(String key:list.keySet()) {
try {
Object currentObject = list.get(key);
sb.append(key+"="+currentObject.getClass().getMethod("toString").invoke(currentObject)+" ");
}
catch(Exception e){}
}
System.out.println(sb.toString());
}

How can I reflectively get a field on a Scala object from Java?

I have the following object:
package com.rock
object Asteriod {
val orbitDiam = 334322.3
val radius = 3132.3
val length = 323332.3
val elliptical = false
}
How can I use Java reflection to get the values of each of those variables?
I can get a method from an object by can't seem to figure out how to get fields.
Is this possible?
Class<?> clazz = Class.forName("com.rock.Asteriod$");
Field field = clazz.getField("MODULE$");
// not sure what to do to get each of the variables?????
Thanks!
This works:
Class<?> clazz = Class.forName("com.rock.Asteriod$");
Object asteroid = clazz.getField("MODULE$").get(null);
Field orbitDiamField = clazz.getDeclaredField("orbitDiam");
orbitDiamField.setAccessible(true);
double orbitDiam = orbitDiamField.getDouble(asteroid);
System.out.println(orbitDiam);
And prints the result 334322.3
Start off with clazz.getDeclaredFields() -- this gives you all the fields declared in the class, as opposed to just the public ones. You may well find them to be private and to actually have synthesized getters. So do check all the methods as well with getDeclaredMethods. Print out everything to see what's going on. And if it isn't too much trouble, post back with findings, it could be an interesting read for others.
I'm not sure what you're trying to achieve, but if you just want the values you don't need reflection:
public class Test {
public static void main(String[] s) {
System.out.println(com.rock.Asteriod$.MODULE$.orbitDiam());
}
}

How can i convert an object to an int in Java?

I'm working in Java and I would like to convert an Object to an int.
I do:
Collection c = MyHashMap.values();
Object f = Collections.max(c);
int NumOfMaxValues = Integer.parseInt(f);
But it's not working. It says:
No suitable method for parseInt.
How can I fix that?
Integer.parseInt()
expects a String. You can use
Integer.parseInt(f.toString())
and override the toString() method in your class.
Ideally, you should use generics to your advantage and have something along the lines of the below:
Map<Object,Integer> myHashMap = new HashMap<Object,Integer>();
Collection<Integer> values = myHashMap.values();
Integer value = Collections.max(values);
if (value != null)
{
int myInt = value;
}
You can't just convert any object to an int. How should that work. Think of a class like this:
class Car {
public String name;
public String owner;
}
You need to define a method yourself. Or you have to find out what specific object that is and how to convert it.
Integer.parseInt(f.toString());

Categories