简体   繁体   English

如何在Java中迭代lambda函数

[英]How to iterate over lambda functions in Java

I was able to do it in Python and my Python code is: 我能用Python完成它,我的Python代码是:

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? 如何通过HashMap在Java中执行相同的操作?

You can use BinaryOperator<Integer> in this case like so : 你可以在这种情况下使用BinaryOperator<Integer> ,如下所示:

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); 注意Map.of("+", add, "-", sub); I'm using Java 10, If you are not using Java 9+ you can add to your map like so: 我正在使用Java 10,如果您不使用Java 9+,您可以像这样添加到地图中:

Map<String, BinaryOperator<Integer>> signs = new HashMap<>();
signs.put("+", add);
signs.put("-", sub);

Ideone demo Ideone演示


Good practice 好的做法

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 : 正如@Boris中的Spider@Holger在评论中已经说过的,最好使用IntBinaryOperator来避免装箱,最后你的代码看起来像这样:

// 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

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. 您可能希望lambda为其他运算符返回double而不是int

Now, simply dump that into a Map : 现在,只需将其转储到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: 但是,对于您的示例,您根本不需要Map

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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM