【问题标题】:Finding neighbors to Points in an ArrayList在 ArrayList 中查找点的邻居
【发布时间】:2012-11-10 18:42:36
【问题描述】:

我最近开始学习 Java,虽然做一个“Conway's Game of Life”风格的程序会是一个很好的开始。一切正常,但我在这部分遇到了一些严重的性能问题:

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;
}

当迭代填充有 PointsArrayList coordList 并检查每个元素有多少邻居时使用该方法。当列表大小达到大约 10000 Points 时,每个周期大约需要 1 秒,而 20000 点需要 7 秒。

我的问题是,什么是更有效的方法来做到这一点?我知道还有其他一些类似的程序也有可用的源代码,但我不想自己做尽可能多的事情,因为该项目的重点是我学习 Java。另外,由于限制,我不想使用常规数组。

【问题讨论】:

    标签: java list arraylist iteration


    【解决方案1】:

    如果您的积分是唯一的,您可以将它们存储在a HashSet 而不是ArrayList。在您当前的设置中,contains 方法将成为 O(1) 操作与 O(n)。这应该会显着加快该部分的速度。

    除了声明之外,您的代码应该保持大部分不变,因为它们都实现了Collection 接口,除非您调用特定于列表的方法,例如get(i)

    【讨论】:

    • 我试试看,谢谢!一个关于HashSet的问题;其中元素的索引是否保持不变?我计划在未来通过另一个由索引链接的对象列表来扩展该程序。但也许这不是做这种事情的正确方法?
    • 这些点必须是唯一的,否则代码 coordList.contains(p) 不会给出正确数量的邻居。
    • hashset 内部使用索引,但是当hashset 调整大小并且索引不被api 暴露时,索引会发生变化。
    • @fredrol 不,索引可能(并且可能)会更改,并且无论如何您都无法通过索引访问元素。您可以使用 LinkedHashSet 在迭代集合时保留插入顺序。
    【解决方案2】:

    就性能而言,我认为最好的办法是使用一个简单的数字(实际上是布尔值)数组来表示网格。由于这是一个学习练习,我将从一个简单的每个单元格一个元素的数组开始,然后可能会进一步将八个相邻的单元格打包成一个字节。

    您所说的“限制”是什么意思并不完全清楚。

    下面有一些有趣的指针:Optimizing Conway's 'Game of Life'

    【讨论】:

    • 感谢您的回复!有限制我指的是阵列的可扩展性。如果我没记错的话,数组的大小是固定的,我希望单元格的数量和坐标能够不受限制地增长。
    【解决方案3】:

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

    二次缩放是一个常见问题,但通常可以通过使用索引数据结构(例如HashSet)来简化为线性。

    【讨论】:

    • 感谢您的回复!正如建议的那样,我更改为 HashSet 并且效果很好。
    猜你喜欢
    • 2020-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-20
    • 1970-01-01
    • 2014-12-17
    • 1970-01-01
    • 2022-08-23
    相关资源
    最近更新 更多