【问题标题】:How can I declare an "infinite" 2D array in Java?如何在 Java 中声明“无限”二维数组?
【发布时间】:2015-09-09 11:44:57
【问题描述】:

我希望我的程序中有一个无限的二维数组。我有以下二维数组代码:

int a[][]=new int[10][10];

但问题是数组是固定长度的,有行值和列值。

【问题讨论】:

  • Java 中的数组固定大小的。
  • “无限”是指一个永远存在的数组?你看过 ArrayLists 吗? (只是让你知道,它们不会永远持续下去)
  • 根据矩阵的稀疏程度,您可以考虑实现一个数组结构,每个数组代表一个巨大(且大部分为空)整体的一小部分。
  • 如果您解释为什么它需要“无限”,您可能会得到更好的答案。您似乎希望在不指定最大 X 或 Y 的情况下为某些 X,Y 坐标设置一个 int 值。您不能在内存中存储无限数据,因此很明显您需要考虑特定 X,Y 坐标值(或2D 值范围)需要初始化和/或修改以及何时需要读取。当需要向用户显示信息时,或者数据非常稀疏时,您可能需要加载有限二维数组的“页面”,Map> 可能是最佳解决方案。

标签: java arrays


【解决方案1】:

正如 Kayaman 评论的那样,java 中的数组是 固定 大小的,如 JLS (§10.3)

中指定的

数组创建表达式指定元素类型、嵌套数组的层数以及至少一层嵌套的数组长度数组的长度可作为最终实例可变长度。

您有 3 种选择,如果第一种在您的情况下是不可能的,您应该使用第二种:

  1. 使用变量来提供所需的数组精确大小:

    int numberOfXElement = // get the elements in dynamic way
    int numberOfYElement = // get the elements in dynamic way
    int a[][]=new int[numberOfXElement][numberOfYElement];
    

最佳选择

  1. 使用具有动态大小的ArrayList,您可以在不关心大小的情况下添加元素(但直到无限,直到Integer.MAX_VALUE)。

    List<List<Integer>> yourList = new ArrayList<ArrayList<Integer>>();
    

    注意:正如 cmets 所指出的,请注意您使用的是Integer and not int


  1. Integer.MAX_VALUE 的大小赋予数组(但必须注意空位)
    正如 cmets 中所指出的,在语法上是正确的表达式,但您需要 ram 内存的音调执行它。而不是这个:

    在创建时给出一个你永远不会到达数组的大数字,但是如果你使用这个选项,你必须小心空位

    int a[][]=new int[8043][8043];
    

    为什么是 8043?我使用了一个快速测试来查看我的实际机器中的最大堆大小,2gb RAM,不关心 i 开始的值,总是中断(在我的机器中,试图创建一个 int[8044][8044]) .

    for (int i = 0; ; i++) {
        int a[][]=new int[i][i];
        System.out.println(i + " " + Arrays.toString(a));
    }
    

【讨论】:

  • 祝第三个好运。除非你有几十亿的内存。我认为列表方法是最好的。
【解决方案2】:

数组的大小是固定的。一旦您以一定长度声明它们,您以后就无法更改它。

您可能想要一个ArrayList,它会在您不断添加项目时动态增加大小。

如果您正在寻找 2D,ArrayList 的 ArrayList 将是选项。

List<List<Integer>> listOfLists = new ArrayList<ArrayList<Integer>>();

如果你不知道为什么我在左侧写了List&lt;List&lt;&gt;&gt; 而不是ArrayList&lt;ArrayList&gt;&gt;,请参考Type List vs type ArrayList in Java

【讨论】:

  • 我会注意到,在这种情况下,对于每个列表的大小,“无限”将是 Integer.MAX_VALUE
  • 应该是 List>,根据他的要求
  • @KevinEsche 我假设infinite 随着时间的推移添加元素。
  • 我想这需要对 Java 新手的健康警告:这个答案很好,但如果你使用这个,请注意你使用的是Integer and not int,因此是operations like == may require a little care
  • @sᴜʀᴇsʜᴀᴛᴛᴀ 在某种意义上是无限的,随着时间的推移将元素添加到行和列
【解决方案3】:

不确定是否可以创建流流,但在 Java 8 中您可以拥有无​​限流。

https://docs.oracle.com/javase/8/docs/api/java/util/stream/IntStream.html#generate-java.util.function.IntSupplier-

【讨论】:

    【解决方案4】:

    equalshashCode 为自己声明一个类Point - 类似这样:

        class Point {
    
            private final int x;
            private final int y;
    
            public Point(int x, int y) {
                this.x = x;
                this.y = y;
            }
    
            public int getX() {
                return x;
            }
    
            public int getY() {
                return y;
            }
    
            @Override
            public int hashCode() {
                int hash = 7;
                hash = 79 * hash + this.x;
                hash = 79 * hash + this.y;
                return hash;
            }
    
            @Override
            public boolean equals(Object obj) {
                if (obj == null) {
                    return false;
                }
                if (getClass() != obj.getClass()) {
                    return false;
                }
                final Point other = (Point) obj;
                if (this.x != other.x) {
                    return false;
                }
                if (this.y != other.y) {
                    return false;
                }
                return true;
            }
    
        }
    

    然后使用:

    Map<Point,Value> twoDArray= new HashMap<>();
    

    将特定位置设置为一个值很简单:

    twoDArray.put(new Point(x,y), value);
    

    如果您的数组可能是稀疏的,那么有许多特殊类可以help

    【讨论】:

    • @OldCurmudgeon 你能更简单地解释一下代码吗
    • @Dhiraj - 使用Map&lt;Point,Value&gt;,而不是声明数组或列表。然后,您只需找到Point 并在Map 中查找即可在二维数组中的任何位置设置/清除/获取值。
    猜你喜欢
    • 2013-05-05
    • 1970-01-01
    • 1970-01-01
    • 2022-01-15
    • 2010-12-21
    • 2014-04-01
    • 2012-02-27
    • 2012-04-01
    • 2020-08-01
    相关资源
    最近更新 更多