如何在Java中迭代lambda函数

Shi*_*hal 12 python java lambda java-8 java-stream

我能用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))
Run Code Online (Sandbox Code Playgroud)

输出是:

8
2
Run Code Online (Sandbox Code Playgroud)

如何通过HashMap在Java中执行相同的操作?

YCF*_*F_L 23

你可以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)));
Run Code Online (Sandbox Code Playgroud)

输出

8
2
Run Code Online (Sandbox Code Playgroud)

请注意Map.of("+", add, "-", sub);我使用的是Java 10,如果您不使用Java 9+,可以像这样添加到地图中:

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

Ideone演示


好的做法

正如@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)));
Run Code Online (Sandbox Code Playgroud)

  • 它是`(int,int) - > int`而不是`Integer` - 所以减少拳击.你的答案很好 - + 1! (3认同)
  • 谢谢@BoristheSpider我之前没有使用`IntBinaryOperator`,我将了解这一点,我看到你的答案并发现你已经使用它了+1 (2认同)
  • 即使使用盒装值,也可以在这里使用`BinaryOperator <Integer>`,它是`BiFunction <Integer,Integer,Integer>`的子类型.此外,您不需要为函数详细声明局部变量:`Map <String,BinaryOperator <Integer >> signs = Map.of("+",(a,b) - > a + b," - " ,(a,b) - > a - b);`; 这更接近OP的Python代码.当然,每当用例允许使用`IntBinaryOperator`时,它更可取,因为它避免了拳击开销(甚至比`BinaryOperator <Integer>`更短)...... (2认同)

Bor*_*der 14

创建一个漂亮的,类型安全的,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);
    }
}
Run Code Online (Sandbox Code Playgroud)

您可能需要返回lambda double而不是int其他运算符.

现在,只需将其转储到Map:

final var operators = Arrays.stream(Operator.values())
        .collect(toMap(Operator::symbol, identity()));
Run Code Online (Sandbox Code Playgroud)

但是,对于您的示例,您根本不需要Map:

Arrays.stream(Operator.values())
        .mapToInt(op -> op.applyAsInt(a,b))
        .forEach(System.out::println);
Run Code Online (Sandbox Code Playgroud)

使用:

import static java.util.function.Function.identity;
import static java.util.stream.Collectors.toMap;
Run Code Online (Sandbox Code Playgroud)