Since Java 8, the Integer class has a static sum method that adds two integers:
public static int sum(int a, int b) {
return a + b;
}
I can pass this method to higher-order functions via Integer::sum which I find more readable than (a, b) -> a + b.
Is there a similar static method for multiplication, so I don't have to write (a, b) -> a * b? I couldn't find one in the Integer class.
You can make it yourself:
public static int mult(int a, int b) {
return a * b;
}
This might seem obvious in retrospect but outside of that I don't believe there's actually a jdk-included method which multiplies for you, except for Math#multiplyExact (Math::multiplyExact), though this might be more than you need.
Math::multiplyExact
static int multiplyExact(int x, int y)
Returns the product of the arguments, throwing an exception if the result overflows an int.
Related
Given this method:
private static Integer getVal(Integer a, Integer b){
return a + b;
}
which can be called as a lambda:
a -> getVal(1, 2)
Is there anyway of turning this into a method reference, something like:
Class::getVal
Thanks
Well, if you are passing constants to the method call, you can create another method that calls the original method:
private static Integer getVal (Integer a) {
return getVal(1,2);
}
then you can use method reference for the second method.
i.e. you can change
a -> getVal(1, 2)
to
ClassName::getVal
That said, it doesn't make much sense.
P.S., it's not clear what's the purpose of a in your lambda expression, since you are ignoring it.
In general you can pass a method reference of a given method if it matches the signature of the single method of the required functional interface.
Example:
public static Integer apply (BinaryOperator<Integer> op, Integer a, Integer b)
{
return op.apply(a,b);
}
Now you can call:
apply(ClassName::getVal)
with your original method.
Here is an example.
interface Operator {
int operate(int a, int b);
}
class Calc {
public static int add(int a, int b) {
return a + b;
}
}
class Main {
public static void main(String[] args) {
// using method reference
int result = operate(1, 2, Calc::add);
// using lambda
int result = operate(1, 2, (a, b) -> Calc.add(a, b));
}
static int operate(int a, int b, Operator operator) {
return operator.operate(a, b);
}
}
You need a functional interface to use method reference (In this example Operator). And you also need a method which accepts an instance of the functional interface as its parermater (In this example operate(int a, int b, Operator operator).
UPDATE
If you need an object wrapper, just change the operate method to
static int operate(ObjectWrapper wrapper, Operator operator) {
return operator.operate(wrapper.getA(), wrapper.getB());
}
And then call the operate method:
int result = operate(wrapper, Calc::add);
getVal() will only be usable as a method reference, in places where a functional interface of an applicable type is expected, such as BiFunction or IntBinaryOperator, or a custom functional interface (as in the answer of zhh)
Example:
public static void main(String[] args) {
Integer result1 = calculate(1, 2, Second::getVal);
Integer result2 = calculateAsInt(1, 2, Second::getVal);
}
private static Integer getVal(Integer a, Integer b){
return a + b;
}
private static Integer calculate(Integer a, Integer b, BinaryOperator<Integer> operator) {
return operator.apply(a, b);
}
private static int calculateAsInt(int a, Integer b, IntBinaryOperator operator) {
return operator.applyAsInt(a, b);
}
This is my Java program code. I overloaded the add function for the data types int and float, but the call add(2.3, 2.4) throws an error, instead of calling add(float, float).
public class Main {
public static void main(String[] args) {
// This calls add(int, int) as expected
System.out.println(add(2,4));
// This call throws an error
System.out.println(add(2.3,3.4));
}
public static int add(int a, int b){
return (a + b);
}
public static float add(float a, float b){
return (a + b);
}
}
You defined the overloaded methods correctly!
What you got wrong is the way you call the methods. You are calling add(2.3,3.4). 2.3 and 3.4 are all doubles. That's why they can't be directly put into a method that accepts floats.
"What? Why are they doubles?" you might ask.
By default, all number literals without a . or e are considered to be ints. And all number literals that has either or both a . or e are considered to be doubles.
To create a float literal, add f to the end of the numbers. i.e. these are all floats:
1f
1000f
1.1f
-9f
1e99f
So you should call your method like this
add(2.3f,3.4f)
There are add methods for int and float, while literal 2.3 has type double. There two ways to fix this:
Use float literals, i.e. 2.3f and 3.4f (notice the f suffix).
Define add method for doubles.
I am trying to understand how Overloading in JAVA works and trying to get grasp of various overloading rules that are applied in case of widening, autoboxing and varargs in JAVA. I am not able to understand what is happening in the following scenario:
package package1;
public class JustAClass {
public static void add(int a, long b) {
System.out.println("all primitives");
}
//public static void add(Integer a, long b) {
// System.out.println("Wraper int, primitive long");
//}
public static void add(int a, Long b) {
System.out.println("Primitive int, Wrapper long");
}
public static void add(Integer a, Long b){
System.out.println("All wrapper");
}
public static void main(String[] args) {
int a = 10;
Integer b = 10;
long c = 9;
Long d = 9l;
add(a,c);
add(a,d);
add(b,c);
add(b,d);
}
}
At this point, I get a compilation error at the third invocation of the add method saying The method is ambiguous for the type Error .
Why is this so? What are the rules for determining which invocation of method will work? What is exactly happening in the following case?
I feel that fourth overloaded add method should work. Please help me understand the concept behind this.
There are 3 stages to method overloading resolution. The first stage doesn't do auto-boxing/unboxing, which means methods that require boxing/unboxing of the passed parameters in order to match one of the overloaded versions of add will only be considered if no match was found that doesn't require boxing/unboxing. That's why 3 of your calls, which have a single exact match, work. Regarding add(b,c);, see below why it's ambiguous.
add(a,c); // exact match to add(int a, long b)
add(a,d); // exact match to add(int a, Long b)
add(b,c); // there is no exact match, so at least one of the passed parameters must
// be boxed or unboxed. However, by unboxing b to int or boxing
// c to Long, each of the three add methods can match, and the
// compiler doesn't know which one to prefer
add(b,d); // exact match to add(Integer a, Long b)
Is it necessary to always initialise the result variable in the function
For example
Public class Calculator
result=addition(a,b);
Public static int addition(int a, int b)
int result;
result =a+b;
return result;
You don't need to have a result variable at all. You need to make sure that every possible way that execution can reach the end of your function (without just throwing an exception) means you get to a return statement, and every return statement has an appropriate express to evaluate, but that doesn't mean you need a separate variable. Your example could be written as:
public static int addition(int a, int b) {
return a + b;
}
If you do use a variable, you'll need to make sure it's definitely assigned before you can read from it, including in a return statement. For example, this won't work because result hasn't been definitely assigned:
public static int addition(int a, int b) {
int result;
if (a < b) {
result = a + b;
}
return result; // Invalid! result may not have a value
}
Where possible, it's generally a good idea to initialize a variable at the point of declaration. So if I were writing this code and wanted a result variable, I'd have:
public static int addition(int a, int b) {
int result = a + b;
return result;
}
Now, looking at your sample code again, you've got another variable used when you call the method:
result=addition(a,b);
It's not clear where that variable would be declared (which is one reason to avoid just posting pseudo-code in questions) but it's completely separate from the result variable in addition, which is local to the addition method. The two variables happen to have the same name, but they're otherwise unrelated. For example, you could easily have:
int sum = addition(a, b);
or call another method with the result instead of assigning it to a variable:
System.out.println(addition(a, b));
Or you could just ignore it entirely:
addtion(a, b); // Valid, but pointless unless there are side-effects
I'm kind of new to Java. I want a method that will use submethods(?). I want something like this:
Math.Addition(1, 1, X in this case, integer of users choice for the output);
The output would be stored in the variable X. But I also want to do something like this:
Math.Subtraction(2, 1, X);
How would I do this?
Create a class called Math.
and Have two methods inside it named 'Addition' and 'Subtraction' with required arguments and put the logic for each inside the method.
public class Math {
public static int X;
public static int Addition(int a, int b, String choice) {
X = a+b;
return X;
}
public static int Substraction(int a, int b, String choice) {
X = a-b;
return X;
}
}
You'll probably need to return the value in order to assign to x. e.g.
X = myClass.add(1,1);