我在下面有这个函数叫做findNeighboringChains(i,j)。传入一个点(x,y),它返回存在于相邻点(x + 1,y),(x - 1,y),(x,y + 1)和(x, y - 1)。如果(x,y)处不存在链,则findChainId(x,y)= -1,否则它将返回ID> = 0.每个(x,y)只能存在一个链。有关更多上下文,这是我在Go游戏中用于查找单元格的相邻链的函数。
我觉得到目前为止我所拥有的有点冗长,但我不确定如何让它变得更好。如果我可以通过循环迭代这些点(x + 1,y)...(x,y - 1),这似乎是理想的。有什么建议吗?
public ArrayList<Integer> findNeighboringChains(int i, int j) {
ArrayList<Integer> neighboringChains = new ArrayList<>();
int tmp = findChainId(i - 1, j);
if (tmp != -1) {
neighboringChains.add(tmp);
}
tmp = findChainId(i + 1, j);
if (tmp != -1) {
neighboringChains.add(tmp);
}
tmp = findChainId(i, j - 1);
if (tmp != -1) {
neighboringChains.add(tmp);
}
tmp = findChainId(i, j + 1);
if (tmp != -1) {
neighboringChains.add(tmp);
}
return neighboringChains;
}
答案 0 :(得分:2)
一种方法是利用内置于Java中的Point对象,并迭代一个点列表 - 每次调用同一段代码。在我的解决方案/重构中,我创建了一个名为“getNeighboringPoints(Point p)”的新方法,该方法检索四个相邻点。然后,在你的函数findNeighboringChains中,你可以在点列表上使用for-each循环进行迭代。
你可以做的这种模式有很多变化,但你认为可以减少冗余是绝对正确的。尝试遵循DRY原则始终是一个好主意。
public ArrayList<Integer> findNeighboringChains(int i, int j) {
ArrayList<Integer> neighboringChains = new ArrayList<>();
Point p = new Point(i, j);
List<Point> neighboringPoints = getNeighboringPoints(p);
for (Point point : neighboringPoints) {
int tmp = findChainId(point.x, point.y);
if (tmp != -1) {
neighboringChains.add(tmp);
}
}
return neighboringChains;
}
/**
*
* @param p
* The input point.
* @return a list of points neighboring point p
*/
private List<Point> getNeighboringPoints(Point p) {
ArrayList<Point> neighboringPoints = new ArrayList<Point>();
neighboringPoints.add(new Point(p.x - 1, p.y));
neighboringPoints.add(new Point(p.x + 1, p.y));
neighboringPoints.add(new Point(p.x, p.y + 1));
neighboringPoints.add(new Point(p.x, p.y - 1));
return neighboringPoints;
}
上述方法的一个好处是,现在您可以在以后发现可能需要对所有相邻点执行另一个操作,并且可以重用方法getNeighboringPoints()。
编辑:
减少冗余的另一种方法是使用extract method技术。
public ArrayList<Integer> findNeighboringChains(int i, int j) {
ArrayList<Integer> neighboringChains = new ArrayList<>();
int tmp = findChainId(i - 1, j);
checkChain(neighboringChains, tmp);
tmp = findChainId(i + 1, j);
checkChain(neighboringChains, tmp);
tmp = findChainId(i, j - 1);
checkChain(neighboringChains, tmp);
tmp = findChainId(i, j + 1);
checkChain(neighboringChains, tmp);
return neighboringChains;
}
private void checkChain(ArrayList<Integer> neighboringChains, int tmp) {
if (tmp != -1) {
neighboringChains.add(tmp);
}
}
这可能会更好,因为它不会强制在已经不使用点的项目上使用点类。 (当有一种方法使用其他一切需要输入两个整数的点时,可能会很烦人。)