Java 在ArrayList中查找点的邻居

Java 在ArrayList中查找点的邻居,java,list,arraylist,iteration,Java,List,Arraylist,Iteration,我最近开始学习Java,虽然做一个“”风格的程序是一件好事情。一切正常,但我在这部分遇到了一些严重的性能问题: static List<Point> coordList = new ArrayList<Point>(); public int neighbors(int x, int y){ int n = 0; Point[] tempArray = { new Point(x-1, y-1), new Point(x, y-1), new Poi

我最近开始学习Java,虽然做一个“”风格的程序是一件好事情。一切正常,但我在这部分遇到了一些严重的性能问题:

static List<Point> coordList = new ArrayList<Point>();

public int neighbors(int x, int y){

    int n = 0;

    Point[] tempArray = { new Point(x-1, y-1), new Point(x, y-1), new Point(x+1, y-1), 
                          new Point(x-1, y  ),                    new Point(x+1, y  ),
                          new Point(x-1, y+1), new Point(x, y+1), new Point(x+1, y+1)};
    for (Point p : tempArray) {
        if (coordList.contains(p))
            n++;
        }

    return n;
}
static List coordList=new ArrayList();
公共整数邻域(整数x,整数y){
int n=0;
点[]tempArray={新点(x-1,y-1),新点(x,y-1),新点(x+1,y-1),
新点(x-1,y),新点(x+1,y),
新点(x-1,y+1),新点(x,y+1),新点(x+1,y+1)};
用于(点p:tempArray){
if(合作列表包含(p))
n++;
}
返回n;
}
该方法用于迭代填充有点的
ArrayList
coordList,并检查每个元素有多少个邻居。当列表大小达到大约10000点时,每个周期大约需要1秒,20000点则需要7秒


我的问题是,什么是更有效的方法?我知道还有其他几种类似的程序,它们的源代码也都有,但是我不能自己做很多,因为这个项目的目的是让我学习Java。此外,由于限制,我不想使用常规数组。

如果点是唯一的,可以将它们存储在中,而不是存储在
数组列表中。
contains
方法将在当前设置中变成O(1)操作,而不是O(n)。这将大大加快该部分的速度


除了声明之外,您的代码应该基本保持不变,因为两者都实现了
集合
接口,除非您调用特定于列表的方法,例如
get(i)

从性能角度看,我认为最好的选择是使用一个表示网格的纯数字(有效的布尔)数组。由于这是一个学习练习,我将从一个简单的每个单元数组一个元素开始,然后可能会将八个相邻单元打包到一个字节中

你所说的“限制”是什么意思还不完全清楚


下面有一些有趣的提示:

您当前的代码以二次方式伸缩
O(n^2)
。您只提供了部分程序。如果您查看整个程序,将有一个循环调用
neights()
,您将看到
neights()
被调用了n次。此外,操作contains()在n中是线性的,因此时间与它们的乘积成正比
n*n


二次缩放是一个常见问题,但通常可以通过使用索引数据结构(如
HashSet

)将其简化为线性,我将尝试一下,谢谢!关于HashSet的一个问题;元素的索引是否保持不变?我计划在将来扩展这个程序,通过索引链接另一个对象列表。但这可能不是这样做的正确方法?点必须是唯一的,否则代码
coordList.contains(p)
不会给出正确的邻居数。哈希集在内部使用索引,但当哈希集调整大小且api未公开索引时,索引会发生变化。@fredrol否索引可能会更改(而且可能会)更改后,您仍然无法通过其索引访问元素。您可以使用LinkedHashSet在对该集合进行迭代时保留插入顺序。感谢您的回答!我指的是数组的可伸缩性。如果我没有弄错的话,数组的大小是固定的,我希望单元格的数量和坐标能够随时间增长ut限制。谢谢你们的回复!按照建议,我改成了散列集,效果很好。