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

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

我有一些类库,正在处理我的数据,这些数据正在读入缓冲区。 是否有可能以某种方式避免一次又一次地复制数组,从而将越来越多的数据部分传递给处理方法? 好吧,这听起来很奇怪,但是在我的特殊情况下,有一个特殊的writer,它将数据分为多个块并将它们分别写入不同的位置,因此它只执行System.arraycopy,获取所需内容并使用该新名称调用底层writer。 子数组。 这会发生很多次。 重构此类代码的最佳方法是什么?

8个解决方案

63 votes

Arrays.asList(array).subList(x, y).

此方法不给您数组,而是2759427639856356333824,它更加灵活。

Ricky Clarkson answered 2020-02-22T23:00:09Z

21 votes

Java中的许多类都将数组的子集作为参数。 例如。 Writer.write(char cbuf [],int off,int len)。 也许这已经足以满足您的用例了。

Markus Kull answered 2020-02-22T22:59:49Z

11 votes

在Java中,没有一种真正的方法可以包装任何数据而不进行复制并接收实际的数组。 您只是无法在现有内存上创建新阵列。 您基本上有2个选择:

使用可以接受数组范围的方法。 已经建议这样做。

使用包装器可以提供接近数组的某种抽象,并且适合许多应用程序。 将在下面描述。

您可以使用buf.array()类的层次结构,尤其是a1,它在整个数组或子范围上提供缓冲区抽象。 人们经常需要它。 这还提供了许多有趣的功能,例如“零复制”翻转和灵活的字节区域表示。

这是使用buf.array()进行包装的示例。这应该非常接近您的需求。 至少对于某些操作。

byte [] a1 = {0, 0, 1, 0};

ByteBuffer buf = ByteBuffer.wrap(a1,1,2);

然后,您可以在buf.array()上进行任何a1操作。

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

Roman Nikitchenko answered 2020-02-22T23:00:56Z

4 votes

如果使用诸如byte []之类的内置数组,则无法在Java中声明子数组。 原因是:数组的长度与数据一起存储,而不是与对它的引用的声明一起存储。 因此,不复制数据的子数组没有可以存储长度的地方!因此,对于基本类型,您可以使用上述有效字节数组副本;对于更高类型(列表),可以使用一些方法。

Joachim answered 2020-02-22T23:01:17Z

2 votes

您可以采用String类所采用的相同方法。 为不可变对象创建一个类,该对象由数组,起始偏移量和结束偏移量构成,并提供对子数组的访问。 这样的对象的用户不必知道整个阵列或子阵列之间的区别。 构造函数不必复制数组,只需存储数组引用及其边界。

rsp answered 2020-02-22T23:01:38Z

1 votes

您可以使用(ArrayList).subList(value1,value2)我相信,也许这对您有帮助? 当然,如果您想使用ArrayList。

Kotten answered 2020-02-22T23:01:58Z

0 votes

也许不使用数组,而应该使用其他类型来维护对原始数组切片的引用,而不是复制数据,类似于C#中的ArraySegment。 这样做的另一个好处是,您还可以按需在原始阵列上移动切片,而无需创建新实例。 伪代码:

public class ArraySegment implements Iterable

{

private int from, to;

private T[] original;

public ArraySegment(T[] original, int from, int to)

{

//constructor stuff

}

public T get(int index)

{

return source[index + from];

}

public int size()

{

return to - from + 1;

}

@Override

public Iterator iterator()

{

//Iterator that iterates over the slice

}

//Can support setters on from/to variables

}

Orestis P. answered 2020-02-22T23:02:18Z

-1 votes

看看Arrays.copyOfRange(***)方法。

Manuel Selva answered 2020-02-22T23:02:38Z

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值