在给定内存约束的情况下,是否有其他方法可以在Java中处理大型2D数组?

在给定内存约束的情况下,是否有其他方法可以在Java中处理大型2D数组?,java,arrays,optimization,multidimensional-array,data-structures,Java,Arrays,Optimization,Multidimensional Array,Data Structures,我试图用Java中的2Dint数组实现一个2D坐标系。我有一个256MB的内存限制,2D网格足够大,可以满足内存需求。是否有另一种数据结构可以做到这一点,同时消耗更少的内存 (编辑:目的是通过为至少访问过一次的坐标设置标志来跟踪网格内的移动。)您根本不需要数组。您现在正在为每个点浪费内存,而实际上只需要存储访问点的坐标。使用一组点仅存储已访问的坐标,并检查该组是否包含坐标,以查看某个点之前是否访问过 因此而不是: int[][] array = new int[width][height];

我试图用Java中的2D
int
数组实现一个2D坐标系。我有一个256MB的内存限制,2D网格足够大,可以满足内存需求。是否有另一种数据结构可以做到这一点,同时消耗更少的内存


(编辑:目的是通过为至少访问过一次的坐标设置标志来跟踪网格内的移动。)

您根本不需要数组。您现在正在为每个点浪费内存,而实际上只需要存储访问点的坐标。使用一组点仅存储已访问的坐标,并检查该组是否包含坐标,以查看某个点之前是否访问过

因此而不是:

int[][] array = new int[width][height];
class Point
{
    public int x;
    public int y;
    public Point(int x, int y)
    {
        this.x = x;
        this.y = y;
    }
    @Override
    public boolean equals(Object o)
    {
        return o instanceof Point && this.x == ((Point)o).x && this.y == ((Point)o).y;
    }
    @Override
    public int hashCode()
    {
        return Integer.valueOf(x).hashCode() ^ Integer.valueOf(y).hashCode();
    }
}

Set<Point> set = new HashSet<Point>();
HashMap<Integer, HashSet<Integer>> map = new HashMap<>();

您有类似于:

int[][] array = new int[width][height];
class Point
{
    public int x;
    public int y;
    public Point(int x, int y)
    {
        this.x = x;
        this.y = y;
    }
    @Override
    public boolean equals(Object o)
    {
        return o instanceof Point && this.x == ((Point)o).x && this.y == ((Point)o).y;
    }
    @Override
    public int hashCode()
    {
        return Integer.valueOf(x).hashCode() ^ Integer.valueOf(y).hashCode();
    }
}

Set<Point> set = new HashSet<Point>();
HashMap<Integer, HashSet<Integer>> map = new HashMap<>();

或者您可以使用地图:

int[][] array = new int[width][height];
class Point
{
    public int x;
    public int y;
    public Point(int x, int y)
    {
        this.x = x;
        this.y = y;
    }
    @Override
    public boolean equals(Object o)
    {
        return o instanceof Point && this.x == ((Point)o).x && this.y == ((Point)o).y;
    }
    @Override
    public int hashCode()
    {
        return Integer.valueOf(x).hashCode() ^ Integer.valueOf(y).hashCode();
    }
}

Set<Point> set = new HashSet<Point>();
HashMap<Integer, HashSet<Integer>> map = new HashMap<>();

如果(!map.contains(x)){
add(x,newhashset());
}
map.get(x)、add(y);
进一步优化选项

如果您知道您的应用程序将访问所有点或至少超过所有点的一半,则可以在达到访问点的50%时切换逻辑。基本上(伪代码):

if(点可视
当然,您需要一些方法,在达到阈值时实际进行交换,从地图或集合中删除所有点,并添加以前不在其中的所有点。之后,您将在访问点时删除点,而不是添加点


这样,在任何给定的时间,最多有一半的点被存储。

尝试
java.nio.Buffer
只将当前正在使用的部分(即视口或类似对象)保存在内存中,其余部分保存在存储器中。这实际上取决于您对该阵列的实际操作。您能否详细说明写入数据的类型(可能不需要完整的32位int类型)、写入方式(可能不需要完全分配的数组,但可以使用动态映射,因为大多数索引始终为空)、读取方式(也许您可以将整个内容存储在某个地方,并始终按照其他人的建议加载要处理的特定块),以及任何其他可能对您有帮助的信息。@MaxVollmer我正在尝试跟踪您可以说的移动。每当访问2D网格上的某个点时,程序都会在这些坐标处设置一个标志,这样,如果重新访问同一点,该标志就可以告诉您。我可以使用
布尔
数组,因为它实际上是一个对/错的事情,但即使这样也无助于记忆问题。请用这些信息更新你的问题。是的,这更有意义。我曾想过使用另一种方法,只存储访问点的坐标(如你所解释的),但即便如此,我还是使用了一个2D数组,并通过数组中已经存在的所有条目搜索每个新条目(以查看它是否已经存在,并因此进行了访问)。这只会产生巨大的计算开销,并降低整个过程的速度。毫无疑问,这是一种更好的方法。谢谢。
if (pointsVisited < numAllPoints / 2)
    values in map or set are visited
else
    values in map or set are **not** visited (all others are)