I have two classes and, in one of them, I want to create a variable that will hold a function from the other class. I want to do this so I can change behaviour dinamically conditionally.
I tried the following prototype which results in a compilation error:
class A {
public String myFn(int a, int b) {
return "<" + a + " " + b + ">";
}
public String myFn2(int a, int b) {
return "(" + a + " " + b + ")";
}
}
class B {
static int mode = 1;
public void fn() {
BiFunction<Integer, Integer, String> fn = null;
if(mode == 1) {
fn = ClassA.myFn(); // This results in an error "Cannot resolve method fn()".
}
else {
//fn = ClassA.myFn2();
}
// next I will use fn ...
}
}
This results in an error "Cannot resolve method fn()".
How can I store the function?
Thanks.
Calling ClassA.myFn() would require the method to be static and this is a method call, you wan't to store the method, not calling it.
Lambda
BiFunction<Integer, Integer, String> fn = null;
if(mode == 1) {
fn = (a, b) -> ClassA.myFn(a, b);
}
Method reference
BiFunction<Integer, Integer, String> fn = null;
if(mode == 1) {
fn = ClassA::myFn;
}
⚠️ Also
both myFn and myFn2 should be static
public static String myFn(int a, int b) {
return "<" + a + " " + b + ">";
}
chosse ClassA or A but they should be matching
class ClassA {
Your method myFn is not static, so you can't access it in a static context like you are trying to do. Your class is also called A, but you reference it as ClassA. Also, when assigning the BiFunction, you assign it to the return value, when you want a lambda expression. Here's an edited copy of your example:
class A {
public static String myFn(int a, int b) { //notice the static keyword
return "<" + a + " " + b + ">";
}
public static String myFn2(int a, int b) { //notice the static keyword
return "(" + a + " " + b + ")";
}
}
class B {
static int mode = 1;
public void fn() {
BiFunction<Integer, Integer, String> fn = null;
if(mode == 1) {
fn = A::myFn; // use a lambda expression, and class is named A
}
else {
//fn = A::myFn2;
}
// next I will use fn ...
}
}
Related
Suppose i have 2 interface which is
interface add{
void add2No(float a, float b);
}
and
interface Minus{
void Minus2No(float a, float b);
}
then on the main method, i already overide the method which is
public class Count implements Add, Minus {
public static void main(String[] args) throws IOException{
//declare var
float a, b;
String temp;
//create object
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
Count obj = new Count();
//User Input
System.out.print("Enter your first Number : ");
temp = br.readLine();
a = Float.parseFloat(temp);
System.out.print("Enter your second Number : ");
temp = br.readLine();
b = Float.parseFloat(temp);
System.out.println("Value of " +a+ " + " +b+ " is : " +obj.Totaladd(float a, float b));
System.out.println("Value of " +a+ " + " +b+ " is : " +obj.TotalMinus(float a, float b));
}
#Override
public void Add2No(float a, float b) {
float TotalAdd = a + b;
}
#Override
public void Minus2No(float a, float b) {
float TotalMinus = a - b;
}
}
Am i using the correct implementation for interface? why there's error when i try to print out the TotalAdd and TotalMinus?
Yes. Because you don't return the results. Currently both methods are void. You could change that. Like,
interface Add {
float add2No(float a, float b);
}
interface Minus {
float minus2No(float a, float b);
}
And then
#Override
public float add2No(float a, float b) {
return a + b;
}
#Override
public float minus2No(float a, float b) {
return a - b;
}
There are three wrong places.
The first wrong place:
Because Java is case sensitive.
The name of your interface method is called add2No, but the name of
your implementation is called Add2No
The second wrong place:
There is a problem with your method parameter passing and the way of
calling. I did not see the Totaladd and Totaladd methods defined in
your Count object.
If you adjust the case, there should only be add2No and Minus2No
methods in Count object.
You need to adjust the name of one of them, and do not pass the type when passing parameters.
For example: obj.Totaladd(float a, float b) should be obj.Totaladd(a, b)
The third wrong place:
If you need to call the method to get the value for calculation, you must adjust the type of the method, it should not be void
In an interview, I was asked to write a function using Generics that adds the numbers and Strings passed to it. The number could be Integer, Double, etc.
If 2 strings are passed to the function, it should append the strings. Finally, the added result should be returned.
I used Lambda as mentioned below.
public class WorkAround {
public static void main(String[] args) {
MyAdd myAdd = new MyAdd();
System.out.println("Adding Integers: " + myAdd.add(1, 2, (a,b) -> a+ b));
System.out.println("Adding Double: " + myAdd.add(1.2, 1.2, (a,b) -> a+ b));
System.out.println("Adding String: " + myAdd.add("James ", "Bond", (a,b) -> a + b));
}
}
class MyAdd {
public <T> T add(T a, T b, BinaryOperator<T> operation) {
return operation.apply(a, b);
}
}
Output:
Adding Integers: 3
Adding Double: 2.4
Adding String: James Bond
But then, I was asked to achieve the same result with Generics alone. Something like the below code snippet.
public class Trial {
public static void main(String[] args) {
MyAdd myAdd = new MyAdd();
System.out.println("Adding Integers: " + myAdd.add(1, 2));
System.out.println("Adding Double: " + myAdd.add(1.2, 1.2));
System.out.println("Adding String: " + myAdd.add("James ", "Bond"));
}
}
class MyAdd {
public <T> T add(T a, T b) {
return a + b;
}
}
Obviously, this did not work because of the following.
The operator + is undefined for the argument type(s) T, T
I found this thread the closet to my question. But that question did not handle Strings. Is there any other way that I might be missing?
We have 2 cases, String or Number. This differentiation should be made.
The following solves the problem.
import java.math.BigDecimal;
public class Trial {
public static void main(String[] args) {
MyAdd myAdd = new MyAdd();
System.out.println("Adding Integers: " + myAdd.add(1, 2));
System.out.println("Adding Double: " + myAdd.add(1.2, 1.2));
System.out.println("Adding String: " + myAdd.add("James ", "Bond"));
}
}
class MyAdd {
public String add(String a, String b) {
return a + b;
}
public <T extends Number> T add(T a, T b){
return (T) new BigDecimal(a.toString()).add(new BigDecimal(b.toString()));
}
}
I am new to Java so I need help.
How can I access the variables of the method method1 and compare them with the variable int c? What should I return?
public static void main (String [] args){
int c = 30;
// I want to compare c with a, for example:
if (c > a)
{
System.out.println(c + " is greater than " + a);
}
}
I want to do the above comparison without touching method1()
public double method1(){
int a = 10; int b = 20;
if (a > b)
{
System.out.println(a + " is greater than " + b);
}
else if (a < b)
{
System.out.println(b + " is greater than " + a);
}
//What should I return?
return ????;
}
if you are writing "int c = 30;" directly below main then it becomes global variable.
Global Variable means: "c" can be accessed inside methods(anywhere in same class).
if you are writing "int c = 30;" inside particular method than you cannot access outside that particular method.
Following is example of global variable.
public static void main (String [] args){
int c = 30;
public double method1(){
int a = 10;
if (a > c)
{
System.out.println(a + " is greater than " + c);
return a;
}
else if (a < c)
{
System.out.println(c + " is greater than " + a);
return b;
}
}
I hope it works for you.
How can I access the variables of the method "method1" [...] without touching the method1()?
You can't.
Local variables in a method are only accessible inside that method. And if that method doesn't give you a way to see them, then without modifying the method, you can't see them.
Since a is always 10, you could do if (c > 10) instead.
I have a certain set of operations that I would like to be able to access dynamically by name.
If I were using JavaScript, I would represent them in a dictionary with the names of the operations as keys and the operation functions as values.
Then, for example, I could ask the user for the name of an operation, display the result of the operation if it exists, and display an error message if it doesn't exist, like so:
var operations = {
addition: function(a, b) { return a + b; },
subtraction: function(a, b) { return a - b; },
multiplication: function(a, b) { return a * b; }
// etc.
};
var a = 4, b = 7;
var opName = prompt("Enter operation name:");
if (opName in operations) {
alert("Result: " + operations[opName](a, b));
} else {
alert("The operation '" + opName + "' does not exist.");
}
How would I do the same thing in Java? I could have a Set<String> of operation names and a function that uses a switch with a case for each operation, but that requires me to repeat each operation name twice, which makes the code more brittle and more tedious to write and maintain.
Is there a reasonably concise DRY pattern for this sort of thing in Java?
This is a lot neater in Java 8 using lambdas:
Map<String, BinaryOperator<Integer>> operators = new TreeMap<>();
operators.put("add", (n1, n2) -> n1 + n2);
operators.put("minus", (n1, n2) -> n1 - n2);
if (operators.containsKey(opName)) {
return operators.get(opName).apply(n1, n2);
}
But I gather from your comments that that is not an option. An alternative is to use an enum to contain your operations so that you can add new operations in one place:
enum Operation {
PLUS {
public int operate(int arg1, int arg2) {
return arg1 + arg2;
}
},
MINUS {
public int operate(int arg1, int arg2) {
return arg1 - arg2;
}
},
...
abstract public int operate(int arg1, int arg2);
}
for (operation: Operations.values()) {
if (operation.name().equals(opName))
System.out.println("result = " + operation.operate(arg1, arg2));
return;
}
}
System.out.println("The Operation " + opName + " does not exist");
public interface Function {
double run(double a, double b);
}
public class addFunction implements Function {
double run(double a, double b) {
return a+b;
}
}
//...
Map<String, Function> operations = new HashMap<string, Function>();
operations.put("add", new addFunction());
//...
String op;
double a, b;
operations.get(op).run(a, b);
You can do the same thing in Java without using Java8:
public interface Operation<T,R> {
R perform(T... args);
}
public void test() {
Map<String, Operation> operations = new HashMap<String, Operation>() {
{
this.put("addition", new Operation<Integer, Integer>() {
public Integer perform(Integer... args) {
return args[0] + args[1];
}});
}
};
String operation = "";
Integer a = 1;
Integer b = 1;
if (operations.containsKey(operation)) {
System.out.println("Result: " + operations.get(operation).perform(a, b));
} else {
System.out.println("The operation '" + operation + "' does not exist.");
}
}
You can move that anonymous class into a separate file if you prefer that, too.
If you need arguments of different types you will have to either juggle with generics or change the argument type to Object and then do casts. Not pretty but that's the price of static typing.
Also the compiler will throw you a warning (using raw Operation) but not much to do here if you want to store operations of different types in the same map. A way out would be to make several maps for different types.
I have a method A in class Test, which generates a number a and b, heres the code for it:
public class Test
{
int a,b;
public void A()
{
a = currentMenu.getCurrentFocusedItem().getItemID();
b = currentMenu.getMenuID();
System.out.println("Inside A ()" + a + " &&" + b);
}
public void B()
{
System.out.println("Inside B ()" + a + " &&" + b);
}
}
Now, I want to acces the a and b int values, into another method B(), in the same
class file.
Need some pointer
If you are working with the same instance of the class Test, the value of a and b as set in method A() should still be visible in method B().
So, the below would work:
Test test = new Test();
test.A();
test.B();
However, the below wouldn't
new Test().A();
new Test().B();
On a side note, methods in Java should always begin with a lowercase letter and use camelcase.
If what you are trying to do is to get the current(and latest) value of a and b,
you could write 2 methods like
public int getA() {
return currentMenu.getCurrentFocusedItem().getItemID();
}
public int getB() {
return currentMenu.getMenuID();
}
and use these methods instead of calling A() to update the values of a,b and then accessing them again in method B.
you can get the a and b values in instance initialization block
public class TestClass {
int a,b;
{
a= 10;
b =45;
}
public void A() {
System.out.println("Inside A ()" + a + " &&" + b);
}
public void B() {
System.out.println("Inside B ()" + a + " &&" + b);
}
}
Using this method, you don't have to call your A() method for populating the values to be used in B()
You can try this too
public void A()
{
a = currentMenu.getCurrentFocusedItem().getItemID();
b = currentMenu.getMenuID();
System.out.println("Inside A ()" + a + " &&" + b);
}
public void B()
{
Test test=new Test();
test.A(); // assign values for a and b
System.out.println("Inside B ()" + a + " &&" + b);
}