要在Kuba Spatny's answer 上进行扩展,您可以创建一个封装对象,该对象为主数组中的数据提供服务,而无需提供任何更改基础数据的机会。
一个例子如下:
public class EncapsulatedData {
private final byte[] data; //<-- only holds a reference to the byte array, no data is copied
private final int start;
private final int range;
public EncapsulatedData(byte[] data, int start, int end){
this.data=data;
this.start=start;
this.range=end-start;
if (end>=data.length || start<0){
throw new IndexOutOfBoundsException();
}
}
public byte get(int index){
if (index>range){
throw new IndexOutOfBoundsException();
}
return data[index+start];
}
public static void main(String[] args){
byte[] bigData=new byte[]{0,1,2,3,4,5,6,7,8,9,10};
EncapsulatedData dataProvider=new EncapsulatedData(bigData,4,9);
System.out.println(dataProvider.get(0)); //prints 4
System.out.println(dataProvider.get(2)); //prints 6
System.out.println(dataProvider.get(4)); //prints 8
System.out.println(dataProvider.get(5)); //prints 9
}
}
在我的例子中, start 和 end 包含在内,所有值都像往常一样从零开始索引。如果您希望接收封装数据的类可以修改您公开的数据范围,您可以添加set(int index, byte value) 方法
使封装范围本身可封装
如果您发现您想进一步将公开范围分解为子范围,您可以通过使封装范围本身可封装来实现。这只需添加一个新的构造函数即可。
EncapsulatedData(EncapsulatedData encapsulateData, int start, int end){
this.data=encapsulateData.data;
this.start=encapsulateData.start+start;
this.range=end-start;
if (end>encapsulateData.range || start<0){
throw new IndexOutOfBoundsException();
}
}
....
....
....
public static void main(String[] args){
byte[] bigData=new byte[]{0,1,2,3,4,5,6,7,8,9,10};
EncapsulatedData dataProvider=new EncapsulatedData(bigData,4,9);
EncapsulatedData dataProvider2=new EncapsulatedData(dataProvider,1,3);
System.out.println(dataProvider2.get(0)); //prints 5
}
这个新封装仍然直接与byte[] 对话,但表现得好像它是一个子封装