I was able to do it in Python and my Python code is:
signs = {"+" : lambda a, b : a + b, "-" : lambda a, b : a - b}
a = 5
b = 3
for i in signs.keys():
print(signs[i](a,b))
And the output is:
8
2
How do I do this same thing in Java through HashMap?
First off, the Lambda function itself cannot be used to iterate through a list. Lambda, by its very nature, is used to write simple functions without the use of defining them beforehand.
The answer is it depends. I have seen cases where using a lambda was slower and where it was faster. I have also seen that with newer updates you get more optimal code.
The lambda expressions are inline code that implements a functional interface without creating an anonymous class. In Java 8, forEach statement can be used along with lambda expression that reduces the looping through a Map to a single statement and also iterates over the elements of a list.
The lambda expression should have the same number of parameters and the same return type as that method. Java has many of these kinds of interfaces built in, such as the Consumer interface (found in the java.util package) used by lists. Use Java's Consumer interface to store a lambda expression in a variable:
Doing this way, we take each element out of the collection for iterating from the first to the end. Thus it is called “external iteration”. We know that in Java, all the collection interfaces (List, Set, Queue, etc) have the Iterable as their super interface. And since Java 8, the Iterable interface introduces a new method:
Lambda expressions are usually passed as parameters to a function: Use a lamba expression in the ArrayList 's forEach () method to print every item in the list: Lambda expressions can be stored in variables if the variable's type is an interface which has only one method.
You can use BinaryOperator<Integer>
in this case like so :
BinaryOperator<Integer> add = (a, b) -> a + b;//lambda a, b : a + b
BinaryOperator<Integer> sub = (a, b) -> a - b;//lambda a, b : a - b
// Then create a new Map which take the sign and the corresponding BinaryOperator
// equivalent to signs = {"+" : lambda a, b : a + b, "-" : lambda a, b : a - b}
Map<String, BinaryOperator<Integer>> signs = Map.of("+", add, "-", sub);
int a = 5; // a = 5
int b = 3; // b = 3
// Loop over the sings map and apply the operation
signs.values().forEach(v -> System.out.println(v.apply(a, b)));
Outputs
8
2
Note for Map.of("+", add, "-", sub);
I'm using Java 10, If you are not using Java 9+ you can add to your map like so:
Map<String, BinaryOperator<Integer>> signs = new HashMap<>();
signs.put("+", add);
signs.put("-", sub);
Ideone demo
As already stated by @Boris the Spider and @Holger in the comments, Its better to use IntBinaryOperator
to avoid boxing, in the end your code can look like this :
// signs = {"+" : lambda a, b : a + b, "-" : lambda a, b : a - b}
Map<String, IntBinaryOperator> signs = Map.of("+", (a, b) -> a + b, "-", (a, b) -> a - b);
int a = 5; // a = 5
int b = 3; // b = 3
// for i in signs.keys(): print(signs[i](a,b))
signs.values().forEach(v -> System.out.println(v.applyAsInt(a, b)));
Create yourself a nice, typesafe, enum
:
enum Operator implements IntBinaryOperator {
PLUS("+", Integer::sum),
MINUS("-", (a, b) -> a - b);
private final String symbol;
private final IntBinaryOperator op;
Operator(final String symbol, final IntBinaryOperator op) {
this.symbol = symbol;
this.op = op;
}
public String symbol() {
return symbol;
}
@Override
public int applyAsInt(final int left, final int right) {
return op.applyAsInt(left, right);
}
}
You may want a lambda that returns double
rather than int
for other operators.
Now, simply dump that into a Map
:
final var operators = Arrays.stream(Operator.values())
.collect(toMap(Operator::symbol, identity()));
For your example though, you don't need a Map
at all:
Arrays.stream(Operator.values())
.mapToInt(op -> op.applyAsInt(a,b))
.forEach(System.out::println);
Using:
import static java.util.function.Function.identity;
import static java.util.stream.Collectors.toMap;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With