Java - 使用lambda表达式的if语句有多短?

时间:2018-01-20 18:15:54

标签: java lambda

首先,我知道有类似的问题。然而,这个问题的答案对我没有帮助。

我有以下代码:

boolean result = fields[x][y + 1].getRing().getPlayer() == player || fields[x][y - 1].getRing().getPlayer() == player || fields[x + 1][y].getRing().getPlayer() == player || fields[x - 1][y].getRing().getPlayer() == player

代码应检查当前播放器上方,下方或旁边是否有当前播放器的响铃。

我试图通过使用lambda表达式使这段代码更具可读性,但我无法正确使用它。不过,我不确定这是否可能。

我尝试将fields[x][y]替换为变量field,然后让field成为fields[x][y+1], fields[x][y-1], fields[x+1][y], fields[x-1][y]

boolean result = field.getRing().getPlayer() == player -> field = {fields[x][y+1], fields[x][y-1], fields[x+1][y], fields[x-1][y]};

但是这给了我一个语法错误,这是我所期望的,因为field = {fields[x][y+1], fields[x][y-1], fields[x+1][y], fields[x-1][y]};将字段设置为数组,并且不会迭代该数组。

有什么办法可以使用lambda表达式缩短这段代码吗?

4 个答案:

答案 0 :(得分:5)

您在4个不同的值上不断重复相同的条件。所以你想要的实际上是避免这种重复,并写一次条件。并且您想要测试4个值中的任何一个是否与条件匹配。首先将4个值存储在集合中:

List<Field> neighbors = Arrays.asList(fields[x + 1][y],
                                      fields[x - 1][y],
                                      fields[x][y + 1],
                                      fields[x][y - 1]);

然后测试这些值是否与条件匹配:

boolean result = neighbors.stream().anyMatch(field -> field.getRing().getPlayer() == player);

这并不一定会使代码更快或更短,但它使它更具可读性和干燥。

答案 1 :(得分:0)

我不认为lambdas会在这里提供帮助。我认为更好的只是介绍一些方法,以便代码更具可读性。

例如,您可以制作四种方法ringAboveringBelowringRightringLeft,这样可以使代码更具可读性。

boolean result = ringAbove(x,y) || ringBelow(x,y) || ringRight(x,y) || ringLeft(x,y);

现在只需实现每个方法,并进行一些重构:

private boolean ringAbove( int x, int y ) {
    return ringAt( x+1, y);

}

其他三种方法可以类似地实施。

我不太了解这段代码,但我们假设它有效。 player需要作为全局变量提供,或者您还需要将其作为参数传递。

private boolean ringAt( int x, int y ) {
     if( x < 0 || y < 0 || x >= fields.length || y >= fields[x].length )
          return false;
     return fields[x][y].getRing().getPlayer() == player;
}

答案 2 :(得分:0)

这是另一个&#34;微小的嵌入式域特定语言&#34;对于 处理职位和领域。它使用Java8 Streams和lambdas。

方法neighborhood 抽象出离散几何邻域的形状的概念,所以 这对于处理所有类型的社区变得非常容易 网格,例如这样的东西:

 #     ###      # #
#x#    #x#     #   #
 #     ###       x
               #   #
                # #

你想要第一种情况,但在下面的代码中,它会非常容易 取代&#34;邻居&#34;的概念通过8格的邻居(第二种情况),或甚至更奇怪的东西,例如国际象棋中允许的骑士移动(第三种情况)。

方法neighboringFields利用纯几何位置的流,对其执行一些额外的检查(以确保您不会离开游戏世界),然后枚举所有字段他们的内容。

然后,您可以使用这些字段流快速检查它们上的各种谓词,例如使用allMatchanyMatch方法,如最后一种方法checkRingsInNeighborhood所示, 所以笨拙的if-expression崩溃到了这个:

return neighboringFields(pos).anyMatch(
    field -> field.getRing().getPlayer() == player
);

以下是完整的代码段:

import java.util.function.*;
import java.util.stream.*;

class NeighborPositions {

    // Mock up implementations of `Ring`, `Player`, and `Position`, 
    // whatever those things are
    public static class Ring {
        private Player player;
        public Ring(Player player) {
            this.player = player;
        }
        public Player getPlayer() {
            return this.player;
        }
    }

    public static class Player {
        private final String name;
        public Player(String name) {
          this.name = name;
        }
    }

    public static class Field {
        private final Ring ring;
        public Field(Ring ring) {
            this.ring = ring;
        }
        public Ring getRing() {
            return this.ring;
        }
    }

    // you probably want to fill it somehow...
    public static int DIM_X = 100;
    public static int DIM_Y = 42;
    public static Field[][] fields = null; 

    /** Position on a rectangular grid */
    public static class Position {
        final int x;
        final int y;
        public Position(int x, int y) {
            this.x = x;
            this.y = y;
        }
    }

    /** Shortcut for accessing fields at a given position */
    public static Field field(Position p) {
        return fields[p.x][p.y];
    }

    /** Generates stream of neighboring positions */
    public static Stream<Position> neighborhood(Position pos) {
        return Stream.of(
            new Position(pos.x + 1, pos.y),
            new Position(pos.x - 1, pos.y),
            new Position(pos.x, pos.y + 1),
            new Position(pos.x, pos.y - 1)
        );
    }

    /** Generates stream of neighboring fields */
    public static Stream<Field> neighboringFields(Position pos) {
        return neighborhood(pos).
            filter(p -> p.x >= 0 && p.x < DIM_X && p.y >= 0 && p.y < DIM_Y).
            map(p -> field(p));
    }

    /** This is the piece of code that you've tried to implement */
    public static boolean checkRingsInNeighborhood(Position pos, Player player) {
        return neighboringFields(pos).anyMatch(
            field -> field.getRing().getPlayer() == player
        );
    }
}

你显然不应该尝试将所有内容整合到一个文件中并声明public static,这只是一个例子。

答案 3 :(得分:0)

您可以创建一个BiFunction<Integer, Integer, Player>,在给定xy坐标的情况下,返回Player

BiFunction<Integer, Integer, Player> fun = (coordX, coordY) ->
    fields[coordX][coordY].getRing().getPlayer();

现在,要检查给定player的戒指是否位于给定坐标对上方,下方或旁边,您可以使用:

boolean result = List.of(
        fun.apply(x, y - 1), 
        fun.apply(x, y + 1), 
        fun.apply(x - 1, y), 
        fun.apply(x + 1, y))
    .contains(player);

这使用Java 9&#39; List.of。如果您尚未使用Java 9,请使用Arrays.asList

此外,它还使用List.contains方法,该方法通过Objects.equals方法检查给定对象是否属于列表,而equals方法又使用null方法(取照顾Player s)。如果equals没有覆盖==,则身份相等1-----------------------1---------------Mamun-----------Assistant--- 1-----------------------2--------------- Salam------------Operator------ 1-----------------------3---------------John--------------Assistant------ 2 ----------------------1--------------- Smith-------------Manager------ 2-----------------------2---------------Roger--------------Director-------- 3-----------------------1---------------Qoel---------------Helper---------- 3-----------------------2---------------Saki---------------Mechanics----- 3-----------------------3----------------Ali-----------------Getman---------- 将用作后备。