首先,我知道有类似的问题。然而,这个问题的答案对我没有帮助。
我有以下代码:
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表达式缩短这段代码吗?
答案 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会在这里提供帮助。我认为更好的只是介绍一些方法,以便代码更具可读性。
例如,您可以制作四种方法ringAbove
,ringBelow
,ringRight
和ringLeft
,这样可以使代码更具可读性。
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
利用纯几何位置的流,对其执行一些额外的检查(以确保您不会离开游戏世界),然后枚举所有字段他们的内容。
然后,您可以使用这些字段流快速检查它们上的各种谓词,例如使用allMatch
和anyMatch
方法,如最后一种方法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>
,在给定x
和y
坐标的情况下,返回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----------
将用作后备。