如何在Java中获取数组的子数组,而不复制数据?

Ill*_*huk 48 java arrays containers

我有一些类库,使用我的数据,它被读入缓冲区.有可能以某种方式避免一次又一次地复制数组,将部分数据更深入地传递到处理方法中吗?好吧,这听起来很奇怪,但在我的特殊情况下,有一个特殊的编写器,它将数据分成块并将它们分别写入不同的位置,因此它只执行System.arraycopy,获得它需要的东西并调用底层编写器,用新的子阵列.这种情况多次发生.重构此类代码的最佳方法是什么?

Ric*_*son 63

Arrays.asList(array).subList(x, y).
Run Code Online (Sandbox Code Playgroud)

这个方法不会给你一个数组,但是a List,它更灵活.

  • 返回由指定数组支持的固定大小的列表.我接受你的道歉. (66认同)
  • 哦! 谢谢 :) (13认同)
  • 为了纠正自己,它不适用于原始类型:`Arrays.asList(new int [] {...})`有类型`List <int []>`(_so_不是我想要的). (3认同)
  • 这个答案谈到了一个子列表,但问题是关于一个子阵列.两件不同的事情. (3认同)
  • 问题的关键在于避免复制.您如何看待上述情况? (2认同)

Mar*_*ull 22

Java中的许多类接受数组的子集作为参数.例如Writer.write(char cbuf [],int off,int len).也许这已经足够你的用例了.


Rom*_*nko 12

没有真正的方法来包装任何数据而不复制和接收 Java中的真实arra y.您无法在现有内存上创建新阵列.你基本上有两个选择:

  • 使用可以接受数组范围的方法.这已经被推荐了.
  • 使用包装提供某种接近数组的抽象,适用于许多应用程序.将在下面描述.

您可以使用java.nio.Buffer类层次结构,尤其是java.nio.ByteBuffer在整个数组或子范围上提供缓冲区抽象.通常这是人们需要的.这也提供了许多有趣的功能,如"零拷贝"翻转和灵活的字节区域表示.

这是使用包装的示例java.nio.ByteBuffer.这应该非常接近您的需求.至少对于一些操作.

byte [] a1 = {0, 0, 1, 0};
ByteBuffer buf = ByteBuffer.wrap(a1,1,2);
Run Code Online (Sandbox Code Playgroud)

然后你可以做buf任何ByteBuffer操作.

只是一个警告,buf.array()返回a1包含所有元素的原始数组(后端).

  • 这是一个知识渊博/深入的答案 (2认同)