【问题标题】:How to make a big array in java如何在java中制作一个大数组
【发布时间】:2013-03-15 21:21:38
【问题描述】:

我想创建一个大小的布尔数组,用户将把它作为输入。例如 - 用户可能会输入一个大数字,例如 1000000000000 ;所以我必须创建一个大小为 1000000000000 的布尔数组。我面临的问题是,我不能将输入存储为 int,因为它不能容纳这么大的数字 - 因此我无法创建数组。Double 是一个选项。我可以将输入数字存储为 double ,但我不知道如何创建 double 数字大小的数组。这就是想法 -

Scanner scanner = new Scanner(System.in);
int target = scanner.nextInt();
boolean [] array_a=new boolean [(target)];

如果目标超出 int 范围,这将不起作用。感谢任何帮助。

更新:谢谢大家。所以你只能创建一个 int 的最大范围(即 2147483648)大小的数组,对吧?内存方面并没有更早地打击我。将采取不同的方法。

【问题讨论】:

  • 您可以使用内存映射文件为存储提供每个布尔值一位的存储,您需要 128 GB 的磁盘。显然您希望拥有相同数量的内存,但没有这么多内存也可以工作(但速度会降低)

标签: java


【解决方案1】:

您可以创建一个抽象,例如数组数组(您甚至可以修改它)。

Object [][] 可以是布尔值或其他任何值。

class LargeArray {

    private final long size;
    private final int sizeI;
    private final int sizeJ;
    private final Object [][] objects;


    public LargeArray() {
        sizeI = 3;//Any reasonable value;
        sizeJ = Integer.MAX_VALUE;
        objects = new Object [sizeI][sizeJ];
        size = sizeI * sizeJ;
    }

    public long size() {
        return size;
    }

    public Object get(long index) {
         int i = index / sizeJ;
         int j = index % sizeJ;
         return objects[i][j];
    }

    public void set(long index, Object object) {
         int i = index / sizeJ;
         int j = index % sizeJ;
         objects[i][j] = object;
    }
}

您也可以更改第一个维度,例如 3。在这种情况下 对象 [3][Integer.MAX_VALUE],您可以创建 (2^31 -1)*3 = 2,147,483,647 * 3 = 6442450941 个元素,您将需要 (2^31 - 1)*3 * 4 =~ 23 GB RAM,这实际上是可能的!!!:)

【讨论】:

    【解决方案2】:

    您不能在 Java 中创建一个大小大于最大正数int 的数组,因为array indexes are int。 (各种List implementations 也是如此。您也许可以创建一个具有更多条目的条目[例如LinkedList],但像getsize 这样的东西开始不工作正常,您只能通过iterator 获得以后的条目[假设事情不只是简单的中断],这需要一段时间。)

    您似乎不太可能真的需要创建一个包含超过 2,147,483,647 个条目的空间的 boolean 数组,但如果您真的这样做,则必须创建多个数组并通过取模数来选择正确的数组您的索引(需要是long)。 (或者使用一些非 JDK 库,如果存在这样做的话。)这将需要 4G 的 RAM。可行,但完全不同的方法会更好的可能性很高。

    但是 1,000,000,000,000 个元素?这将需要大约 1-2 TB 的 RAM。正如 NPE 所说,如果你不是在超级计算机上运行,​​你就不会拥有它。

    【讨论】:

    • 其实你可以创建一个比这个大的LinkedList。但是你不想在上面使用get(int) :-)
    • @StephenC:你试过这样做吗?我强烈怀疑它会破裂。在任何情况下,内存使用都会很大(所有那些双链接指针)。
    • 我没试过。但是size() 的 List javadoc 特别允许列表 > MAX_INT
    • @StephenC:哦,原来如此。
    • 谢谢 :) 明白了。采取差异。接近。
    【解决方案3】:

    必须创建一个大小为 1000000000000 的布尔数组。我面临的问题是,我无法将输入存储为 int

    你的问题不在于。您的主要问题是您没有足够的内存来分配具有 1,000,000,000,000 个元素的数据结构(即使您克服了 int 索引的限制)。

    您需要重新考虑算法。

    【讨论】:

    • 即使您确实有一个具有那么多可寻址内存的系统,Java 数组也仅限于 (2^31 - 1) 个元素。这个限制更为根本。
    • @StephenC:这就是我说“数据结构”而不是“数组”的原因。人们可以轻松地创建一个数组或类似的数组,但这只会推迟不可避免的事情。
    • 2,147,483,647 个字大小的条目只有大约 4G 的内存。很多系统都有。不过,并不是说我不同意你的 main 观点。 :-)
    • @T.J.Crowder:这个数字是从哪里来的? OP 正在谈论 1,000,000,000,000 个元素。
    • 其实你说的是“数组”。
    【解决方案4】:

    首先:您确实需要一个充分的理由来分配这么多内存。正如其他人所说,您可能需要重新考虑这种方法。

    一些建议:要么将要分配的数量限制在某个最大值,要么将其存储在文件中并寻找数据或根据需要进行分配(惰性分配)。如果数据稀疏(实际布尔值很少,但索引分布非常广泛),则最好使用地图。如果它主要是零,请考虑只存储零:)

    第二:理论上可以分配 8 * 最大数组大小的布尔值,如果你打包这些位。请参阅此讨论以获取灵感:Implementing a C style bitfield in Java

    【讨论】:

      【解决方案5】:

      如何使用 HashMap 并使用长键和布尔值。

      你有几个优点。
      1.可以使用long范围内的索引
      2.您不必担心使用的项目索引的最大大小。只要它很长,它就会起作用
      3. 你没有预先为整个集合分配内存。相反,您只会使用您需要的内存。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-04-08
        • 1970-01-01
        • 2011-06-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-05-02
        相关资源
        最近更新 更多