【问题标题】:In Java: is where a way to create a subarray that will point to a portion of a bigger array?在 Java 中:在哪里可以创建一个指向更大数组的一部分的子数组?
【发布时间】:2010-10-11 17:30:27
【问题描述】:

学习Java,所以请温柔一点。理想情况下,我需要创建一个字节数组,指向更大数组的一部分:

byte[] big  = new byte[1000];

// C-style code starts
load(file,big);

byte[100] sub = big + 200; 

// C-style code ends

我知道这在 Java 中是不可能的,我想到了两种解决方法,包括:

  1. big 的部分复制到 sub 中,遍历 big

  2. 或者编写自己的类来引用 big + offset + size 并通过使用 big 作为实际底层的访问器方法实现“子数组”数据结构。

我要解决的任务是将文件加载到内存中,然后通过类获得对与文件一起存储的记录的只读访问权限。速度是最重要的,因此理想情况下我想避免复制或访问器方法。因为我正在学习 Java,所以我想坚持下去。

我还有其他选择吗?如果我没有很好地解释任务,请提出问题。

【问题讨论】:

  • 不一致:byte[] sub = new byte[100];为 100 字节保留空间,但赋值 sub = big + 200;只存储一个指针。
  • 斯甘斯兰特,真的。也移到了 C 风格的代码。

标签: java performance


【解决方案1】:

在 Java 中无法将数组创建为其他数组的“视图”。但是您可以使用java.nio.ByteBuffer,这基本上是您在解决方法#2 中建议的类。例如:

ByteBuffer subBuf = ByteBuffer.wrap(big, 200, 100).slice().asReadOnlyBuffer();

不涉及复制(尽管创建了一些对象)。作为一个标准库类,我还假设 ByteBuffer 更有可能接受特殊处理。 JVM 的“JIT”优化比自定义优化。

【讨论】:

    【解决方案2】:

    查看 java.lang.String 的源代码(它将在 src.zip 或 src.jar 中)。你会看到他们有一个 cahrs 数组,然后是一个开始和结束。所以,是的,解决方案是使用一个类来做到这一点。

    Here is a link to the source online

    感兴趣的变量是:

    • 价值
    • 偏移量
    • 计数

    substring 可能是一个很好的起点。

    如果您想直接从文件中读取,请使用 java.nio.channels.FileChannel 类,特别是 map() 方法 - 这将允许您使用内存映射 I/O,这将非常快并且比复制使用更少的内存到数组。

    【讨论】:

    • 在读取大文件时记住 String 实现:substring 和 split 方法保存对原始字符串的引用。所以如果你读取一个 1 GB 的文件,并且只存储每行的第一个单词,那么空间需求仍然是 1 GB!!!
    【解决方案3】:

    如果你想通过低级访问快速读取文件,请检查 java nio 的东西。这是来自java almanac 的示例。

    您可以使用映射的字节缓冲区在文件内容中导航。

    【讨论】:

    • 感谢 Miguel,但似乎在幕后,这个变通办法 1 和 2 相结合。
    猜你喜欢
    • 1970-01-01
    • 2016-06-19
    • 2016-02-04
    • 2021-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多