java是确定坐标是否为顶点/边界坐标的有效方法?
想象一个笛卡尔平面,每个单元对象代表平面上的一个点(该平面将是迷宫)。在构建迷宫时,我想知道一个单元对象是顶点(四个角点)还是边界点(迷宫边缘上的任何单元,顶点也是边界点)
我需要知道,以便我可以添加相邻单元作为特定单元的邻居(我正在创建一个带有节点的图形结构)。不同的边界对哪些单元格是邻居有不同的要求(例如,右上角顶点不能有y+1或x+1的邻居,因为它在迷宫之外,而左下角顶点不能有y-1或x-1)
我是如何通过大量的if语句来实现这一点的,我觉得这并不是一个很好的实践。所以我想问,是否有更好的方法来知道一个点是什么类型的坐标
我是这样做的:
private String typeOfBorderCell(Cell cell){
if (!isBorderCell(cell)){
throw new IllegalArgumentException("cell is not a border cell");
}
double x = cell.getCoordinate().getX();
double y = cell.getCoordinate().getY();
// Vertices
if (x == 0 && y == 0){
return "bottom-left";
}
else if (x == 0 && y == height - 1){
return "top-left";
}
else if (x == width - 1 && y == 0){
return "bottom-right";
}
else if (x == width - 1 && y == height - 1){
return "top-right";
}
// Non-Vertices
else if (x == 0 && (y > 0 && y < height - 1)){
return "left";
}
// and so on for the other three non-vertex borders
}
高度/宽度是迷宫的大小,但我必须减去1,因为迷宫坐标从原点(0,0)开始,因此5x5迷宫的y最大值为4,x最大值为4
这样做,我将得到总共8个条件语句(使用此方法的方法还需要一个包含8个case的switch语句)。有没有一种更有效的方法可以在没有一堆条件语句的情况下实现这一点
# 1 楼答案
我发现,相对于一长串
if
语句,enum是一个相当优雅的替代方案。下面是一个示例(使用Java 8):您可以将其用于
CellType.valueOf(0, 4)
这样的代码,它将返回CellType.TOP_LEFT
与if语句集相比,我更喜欢这个习惯用法,因为它将谓词放在一个位置,使它们易于识别和更改
这也会导致你的“单元格类型”不是一个字符串,这是一个好主意,如果你以后想添加逻辑到它。例如,通过向枚举本身添加处理单元类型的逻辑,可以避免问题中提到的switch语句。此外,与字符串相比非常容易出错。你可能会在一个地方更改字符串,最终导致难以检测的错误。如果更改枚举,会立即出现语法错误
下面简要介绍一下它的工作原理。A
BiPredicate
是一个函数接口,它接受两个整数(x和y)并返回一个布尔值。每个CellType
成员都有一个谓词,用于测试给定的x和y是否代表该类型的单元格。对于边缘单元类型,使用lambda表达式提供条件。对于顶点,构造函数采用两种边单元类型,并通过测试单元是否同时满足两种边条件来构造一个新谓词。例如,TOP_LEFT
测试单元格是否位于上边缘和左边缘valueOf
方法查找满足给定单元格的所有单元格类型,然后返回优先级最高的单元格类型。优先级确保返回顶点而不是边。如果没有匹配的单元格类型,则返回OTHER
(对于非边非vertix)