Chỉ nhận một phần của một mảng trong Java?


274

Tôi có một mảng các số nguyên trong Java, tôi chỉ muốn sử dụng một phần của nó. Tôi biết trong Python bạn có thể làm một cái gì đó giống như mảng này [index:] và nó trả về mảng từ chỉ mục. Là một cái gì đó như thế này có thể có trong Java.

Câu trả lời:


443

Độ dài của một mảng trong Java là bất biến. Vì vậy, bạn cần sao chép phần mong muốn dưới dạng một mảng mới.
Sử dụng copyOfRangephương thức từ lớp java.util.Arrays :

int[] newArray = Arrays.copyOfRange(oldArray, startIndex, endIndex);

start Index là chỉ số ban đầu của phạm vi được sao chép, bao gồm.
end Index là chỉ mục cuối cùng của phạm vi được sao chép, độc quyền. (Chỉ số này có thể nằm ngoài mảng)

Ví dụ:

   //index   0   1   2   3   4
int[] arr = {10, 20, 30, 40, 50};
Arrays.copyOfRange(arr, 0, 2);          // returns {10, 20}
Arrays.copyOfRange(arr, 1, 4);          // returns {20, 30, 40}
Arrays.copyOfRange(arr, 2, arr.length); // returns {30, 40, 50} (length = 5)

dường như có một giới hạn kích thước? chỉ điều này hoạt động: Arrays.copyOfRange(Thread.currentThread().getStackTrace(),1,255)thay vì 255 Tôi không thể sử dụng Integer.MAX_VALUE, trong trường hợp tôi không muốn có được chiều dài thực sự
Aquarius Power

@AquariusPower giới hạn kích thước là kích thước mảng và nó có thể lớn hơn 255. Bạn không thể cung cấp endIndexkích thước lớn hơn kích thước của mảng được truyền làm đối số đầu tiên. Vì vậy, nếu bạn muốn có một bản sao đầy đủ, hãy tạo một biến tham chiếu đến mảng này và sử dụng Arrays.copyOfRange(var, 0, var.length)hoặcArrays.copyOf(var, var.length)
elias

Tôi sẽ phải tạo một var cục bộ cho mảng con stacktrace, nhưng tôi thấy rằng nó hoạt động !!! Arrays.copyOfRange(Thread.currentThread().getStackTrace(),1,Short.MAX_VALUE)
Sức mạnh Bảo Bình

Hãy cẩn thận về ArrayIndexOutOfBoundsException.
elias

1
có một vấn đề khác Điều gì sẽ xảy ra nếu tôi cần phân chia chuỗi chuỗi có độ dài 500K thành các chuỗi con 250K. Các phương thức này chấp nhận interegr mà tối đa là 65000.
Vishnu Dahatonde

31

Bạn có thể gói mảng của bạn dưới dạng một danh sách và yêu cầu một danh sách con của nó.

MyClass[] array = ...;
List<MyClass> subArray = Arrays.asList(array).subList(index, array.length);

22

Có, bạn có thể sử dụng Arrays.copyOfRange

Nó cũng làm điều tương tự (lưu ý có một bản sao: bạn không thay đổi mảng ban đầu).


2
Điều đó nói rằng, nếu bạn không muốn tạo một bản sao rõ ràng, bạn sẽ cần sử dụng một ListsubListnhư được nêu trong câu trả lời của @ K-ballo.
Louis Wasserman

Đúng rồi. Java không có các phương tiện cắt mảng mà các ngôn ngữ hiện đại hơn cung cấp.
Denys Séguret

Tôi không chắc liệu tôi có giải thích theo cách đó không, nhưng ... vâng, Java không cung cấp dịch vụ cắt mảng. (Điều đó nói rằng, có một số lợi thế để tiếp cận này: giảm khả năng rò rỉ bộ nhớ, giảm mảng overhead bằng cách tránh các trường bổ sung, vv Bạn có thể đi một trong hai cách.)
Louis Wasserman

Vâng, bạn lại đúng (và tôi đã không cố bắt đầu một cuộc chiến rực lửa;)). Cắt lát làm cho GC rất phức tạp. Và khi Java đã thử cắt lát dựa trên đối tượng trong Chuỗi, điều đó càng làm cho nó rõ ràng hơn rằng điều này là nguy hiểm .
Denys Séguret

10

Bạn co thể thử:

System.arraycopy(sourceArray, 0, targetArray, 0, targetArray.length);// copies whole array

// copies elements 1 and 2 from sourceArray to targetArray
System.arraycopy(sourceArray, 1, targetArray, 0, 2); 

Xem javadoc cho Hệ thống .


3
Tôi chỉ thích cách đây chính xác là cách Arrays.copyOf () và Arrays.copyOfRange () thực sự được thực hiện (sans giới hạn kiểm tra) và nó không nhận được phiếu nào trong khi trình bao bọc phương thức tiện ích cao hơn một chút sẽ bỏ phiếu mặc dù có niên đại System.arraycopy trở lại năm 1995.
Dave

1
Tôi đoán nó không đủ "hiện đại" đối với một số người.
Dave

Tôi thích đi học cũ, không có chuông sáng và còi chỉ là máy móc cần thiết. Giống như memcpy trong C
StvnBrkdll

Nhưng việc sử dụng Arrayays.copyOfRange () làm tăng khả năng đọc và giảm đáng kể khả năng xảy ra lỗi.
Florian F

7

Nếu bạn đang sử dụng Java 1.6 trở lên, bạn có thể sử dụng Arrays.copyOfRangeđể sao chép một phần của mảng. Từ javadoc:

Sao chép phạm vi chỉ định của mảng đã chỉ định thành một mảng mới. Chỉ số ban đầu của phạm vi (từ) phải nằm giữa 0 và original.length, bao gồm. Giá trị tại original[from]được đặt vào phần tử ban đầu của bản sao (trừ khi from == original.lengthhoặc from == to). Các giá trị từ các phần tử tiếp theo trong mảng ban đầu được đặt vào các phần tử tiếp theo trong bản sao. Chỉ mục cuối cùng của phạm vi ( to), phải lớn hơn hoặc bằng from, có thể lớn hơn original.length, trong trường hợp đó falseđược đặt trong tất cả các thành phần của bản sao có chỉ số lớn hơn hoặc bằng original.length - from. Độ dài của mảng trả về sẽ là to - from.

Đây là một ví dụ đơn giản :

/**
 * @Program that Copies the specified range of the specified array into a new 
 * array.
 * CopyofRange8Array.java 
 * Author:-RoseIndia Team
 * Date:-15-May-2008
 */
import java.util.*;
public class CopyofRange8Array {
    public static void main(String[] args) {
       //creating a short array
       Object T[]={"Rose","India","Net","Limited","Rohini"};
        // //Copies the specified  short array upto specified range,
        Object T1[] = Arrays.copyOfRange(T, 1,5);
        for (int i = 0; i < T1.length; i++) 
            //Displaying the Copied short array upto specified range
            System.out.println(T1[i]);
    }

}



-2

Bạn có thể sử dụng subList(int fromIndex, int toIndex)phương thức trên mảng số nguyên của mình, đại loại như thế này:

import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<Integer> arr = new ArrayList<>();
        arr.add(1);
        arr.add(2);
        arr.add(3);
        arr.add(4);
        List<Integer> partialArr = arr.subList(1, 3);

        // print the subArr
        for (Integer i: partialArr)
            System.out.println(i + " ");
    }
}

Đầu ra sẽ là : 2 3.

Lưu ý rằng subList(int fromIndex, int toIndex)phương thức thực hiện trừ 1 trên biến thứ 2 mà nó nhận được (var2 - 1), tôi không biết chính xác tại sao, nhưng đó là những gì xảy ra, có thể để giảm cơ hội vượt quá kích thước của mảng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.