2014-12-15 16 views
5

Trong java, tôi tự hỏi làm thế nào tôi có thể nhận được byte[] của khác byte[] từ vị trí cụ thể mà không cần sao chép nó?cách lấy byte [] từ vị trí cụ thể của byte khác [] mà không cần sao chép?

Ví dụ:

byte[] bytes1 = new byte[100]; 
for (int i = 0; i < 100; i++) { 
    bytes1[i] = (byte)(i+1); 
} 
byte[] byte2; 

Làm thế nào tôi có thể chỉ byte2 để byte1 ở vị trí 10? Tôi muốn rằng byte2 sẽ có: [0] = 10, [1] = 11, [2] = 12

Có thể không?

Tôi đã thử với ByteBuffer nhưng không thành công.

+1

Thật không may, bạn không thể. Có lẽ đó là một tùy chọn: http: //fastutil.di.unimi.nó/docs/it/unimi/dsi/fastutil/bytes/ByteList.html # subList (int, int)? –

+0

@LyubomyrShaydariv tiện ích đó được hỗ trợ bởi một 'Danh sách ', xem câu trả lời của tôi. –

+0

@StefanoSanfilippo nó không được hỗ trợ bởi một 'Danh sách ' - http://grepcode.com/file/repo1.maven.org/maven2/it.unimi.dsi/fastutil/6.5.1/it/unimi/dsi/ fastutil/bytes/ByteArrayList.java - nó có nội bộ 'byte [] a', không phải' Byte [] a'. Fastutil được thiết kế cho các bộ sưu tập và bản đồ nguyên thủy hiệu quả. –

Trả lời

0

Tôi rất tiếc, bạn không thể.

Trong java mọi mảng là một đối tượng. Ngoài việc lưu trữ các phần tử, nó cũng lưu trữ chiều dài của mảng.

4

Điều duy nhất ngắn screwing với internals VM (vâng, nó thể làm con trỏ số học với ví dụ to-and-fro JNI cuộc gọi) đang sử dụng cách tương tự như Arrays.asList(bytes1).subList(startIndex, endIndex) (lưu ý rằng asList() không hoạt động với các mảng nguyên thủy của chính nó, bạn phải viết hoặc tìm thấy trên 'một thực thi tương tự cho nguyên thủy; http://fastutil.di.unimi.it/docs/it/unimi/dsi/fastutil/bytes/ByteList.html#subList%28int đến đây) - lưu ý rằng bạn sẽ nhận được một số List xem theo cách này, không phải là byte[], vì điều đó về cơ bản là không thể trong Java (ngoại trừ VM hack, nhớ tôi).

Ngoài ra, làm những gì bạn nói - sử dụng java.nio.Buffer, ByteBuffer đặc biệt, vì đó là các đối tác Java của con trỏ tới bộ nhớ; với mảng được hỗ trợ theo mảng ByteBuffer, bạn có thể truy cập mảng trực tiếp hoặc truy cập bộ đệm theo cách trừu tượng/sửa đổi (ví dụ: có bù đắp).

ByteBuffer bytes1 = ByteBuffer.allocate(100); 
for (int i = 0; i < 100; i++) { 
    bytes1.put((byte)(i+1)); 
} 
bytes1.position(offset); 
ByteBuffer byte2 = bytes1.slice(); 

hoặc thậm chí

byte[] bytes1 = new byte[100]; 
for (int i = 0; i < 100; i++) { 
    bytes1[i] = (byte)(i+1); 
} 
ByteBuffer bytes1 = ByteBuffer.wrap(bytes1); 
bytes1.position(offset); 
ByteBuffer byte2 = bytes1.slice(); 
+3

'Arrays.asList (bytes1)' - sẽ không hoạt động như mong đợi đối với 'byte [] bytes1'. –

+0

@AlexeyShestakov true, IFTFY – vaxquis

+0

byte [] bytes = byte mới [100]; cho (int i = 0; i <100; i ++) { byte [i] = (byte) (i + 1); } ByteBuffer bf1 = ByteBuffer.wrap (byte); bf1.position (15); ByteBuffer bf2 = bf1.slice(); byte [] byes2 = bf2.array(); nhưng byte2 không chứa 15, 16, 17. nó chứa 1, 2, 3 ... do đó ByteBuffer không giúp – user3668129

3

Thật không may, bạn không thể. Những gì bạn đang yêu cầu về cơ bản là số học con trỏ C/C++, và không có điều như vậy trong Java.

Tuy nhiên, nếu bạn sẵn sàng sử dụng giao diện khác, bạn có thể có một số may mắn với Commons Primitives ArrayByteList. Nó không phải là một đơn giản List<Byte>, vì nó được hỗ trợ bởi một mảng thực sự của byte s - do đó không có phí bộ nhớ do sử dụng các đối tượng Byte. Bạn vẫn sẽ có một số chi phí đối tượng, nhưng đó là chấp nhận được trong các trường hợp thực tế.

Quan trọng nhất, nó hỗ trợ lát qua phương pháp ArrayByteList.subList(), trong đó không tạo bản sao. Bạn có thể kiểm tra source code, lát được thực hiện như một tham chiếu đến mảng ban đầu cộng với hai điểm đánh dấu cho vị trí bắt đầu và kết thúc.

Tuy nhiên, hãy nhớ rằng tránh sao chép có nghĩa là các thay đổi đối với lát được phản ánh trong mảng ban đầu. Đó có thể là những gì bạn muốn, nhưng vẫn rất cẩn thận - đặc biệt là nếu bạn không đến từ một nền C/C++, nơi mà những điều này là thực tế phổ biến.

Các vấn đề liên quan