Tôi có một số thư viện lớp học, làm việc với dữ liệu của tôi, đang được đọc vào bộ đệm. Có thể bằng cách nào đó để tránh sao chép mảng một lần nữa và một lần nữa, đi qua các phần dữ liệu sâu hơn và sâu hơn vào các phương pháp xử lý? Nghe có vẻ kỳ lạ, nhưng trong trường hợp cụ thể của tôi, có một nhà văn đặc biệt, chia dữ liệu thành các khối và viết chúng vào các vị trí khác nhau, vì vậy nó chỉ thực hiện System.arraycopy, nhận được những gì nó cần và gọi cho người viết bên dưới. mảng phụ. Và điều này xảy ra nhiều lần. Cách tiếp cận tốt nhất để cấu trúc lại mã như thế nào?Làm thế nào để có được một mảng phụ của mảng trong Java, mà không cần sao chép dữ liệu?
Trả lời
Nhiều lớp trong Java chấp nhận một tập con của một mảng làm tham số. Ví dụ. Writer.write (char cbuf [], int off, int len). Có lẽ điều này đã đủ cho usecase của bạn.
Đây là cách tiếp cận đơn giản nhất, vì vậy tôi sẽ thử nó. –
Xem qua phương thức Arrays.copyOfRange(***)
.
Từ javadoc: "Sao chép phạm vi được chỉ định của mảng được chỉ định vào một mảng mới", đó không phải là những gì OP muốn. – f1sh
Bạn có thể thực hiện cùng phương pháp như lớp học String
; tạo một lớp cho các đối tượng bất biến được xây dựng từ một mảng, một bù bắt đầu và một bù đắp cuối cung cấp quyền truy cập vào mảng phụ. Người dùng của một đối tượng như vậy không cần phải biết sự khác biệt giữa toàn bộ mảng hoặc mảng phụ. Hàm khởi tạo không phải sao chép mảng, chỉ lưu trữ tham chiếu mảng và ranh giới của nó.
Arrays.asList(array).subList(x, y).
Phương pháp này không cung cấp cho bạn một mảng, nhưng là List
, linh hoạt hơn nhiều.
Bạn có thể sử dụng (ArrayList) .subList (value1, value2) i belive, có lẽ điều đó có thể hữu ích trong trường hợp của bạn? Đó là ofcourse nếu bạn muốn sử dụng một ArrayList.
là câu trả lời này chưa được đưa ra? – dldnh
Không có cách nào thực sự để bao bọc mọi dữ liệu mà không cần sao chép và nhận arra thực y trong Java. Bạn chỉ không thể tạo mảng mới trên bộ nhớ hiện có. Về cơ bản, bạn có 2 tùy chọn:
- Sử dụng các phương pháp có thể chấp nhận phạm vi mảng. Điều này đã được đề nghị.
- Sử dụng trình bao bọc cung cấp một số loại trừu tượng gần với mảng và phù hợp với nhiều ứng dụng. Sẽ được mô tả dưới đây.
Bạn có thể sử dụng phân cấp lớp học java.nio.Buffer
, đặc biệt là java.nio.ByteBuffer
cung cấp khả năng trừu tượng bộ đệm trên toàn bộ mảng hoặc dải ô phụ. Thường thì đó là những gì mọi người cần. Điều này cũng cung cấp nhiều khả năng thú vị như 'zero copy' flip và biểu diễn vùng byte linh hoạt.
Dưới đây là ví dụ về gói sử dụng java.nio.ByteBuffer
. Điều này sẽ rất gần với những gì bạn cần. Ít nhất là đối với một số hoạt động.
byte [] a1 = {0, 0, 1, 0};
ByteBuffer buf = ByteBuffer.wrap(a1,1,2);
Sau đó, bạn có thể thực hiện trên buf
mọi hoạt động ByteBuffer
.
Chỉ cần cảnh báo, buf.array()
trả về mảng gốc a1
(phụ trợ) với tất cả các phần tử.
Vì vậy, ngay cả khi tôi làm buf = ByteBuffer.wrap (a1, 1, 2) ... buf.array() sẽ vẫn trả về {0, 0, 1, 0}. Vậy ý tưởng này không thể được sử dụng để có được một subarray? – Benitok
Bạn chỉ không thể nhận được mảng phụ thực mà không cần sao chép trong Java. Vì vậy, trình bao bọc được sử dụng. Danh sách một được minh họa trước và trừu tượng bộ đệm là một cái khác. Tôi có thể nói nó hữu ích hơn nhiều so với phạm vi byte của bộ nhớ nhưng đối với các mảng đối tượng phức tạp Danh sách là phổ biến hơn. –
Không có cách nào để khai báo một subarray trong Java nếu bạn sử dụng được xây dựng trong mảng như byte []. Lý do là: Độ dài của mảng được lưu trữ với dữ liệu, không phải với khai báo tham chiếu đến nó. Do đó một subarray mà không sao chép dữ liệu không có nơi mà nó có thể lưu trữ độ dài! Vì vậy, đối với các loại cơ bản, bạn có thể sử dụng các bản sao mảng byte hiệu quả được đề cập và cho các loại cao hơn (Danh sách) có các phương pháp có sẵn.
Điều gì về việc thực hiện một số phép thuật JNI trong C++? Có thể là một thảm họa từ GC POV. –
có thể trùng lặp của [Lấy một phân đoạn của một mảng trong Java mà không tạo một mảng mới trên heap] (http://stackoverflow.com/questions/1100371/grab-a-segment-of-an-array-in-java- không có-tạo-một-mới-mảng-trên-đống) –