Отримати лише частину масиву на Java?


275

У мене є масив Integers на Java, я хотів би використовувати лише його частину. Я знаю, що в Python ви можете зробити щось подібне до цього масиву [index:], і він повертає масив з індексу. Чи можливо щось подібне можливо на Java.

Відповіді:


444

Довжина масиву в Java незмінна. Отже, потрібно скопіювати потрібну частину у новий масив.
Використовуйте copyOfRangeметод з класу java.util.Arrays :

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

startIndex - початковий індекс діапазону, який потрібно скопіювати, включно.
endIndex - це кінцевий індекс діапазону, який потрібно скопіювати, ексклюзивно. (Цей індекс може лежати поза масивом)

Наприклад:

   //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)

здається, обмеження розміру? тільки це працює: так Arrays.copyOfRange(Thread.currentThread().getStackTrace(),1,255)як замість 255 я не можу використовувати Integer.MAX_VALUE, якщо я не хочу отримати реальну довжину
Водолій Сила

@AquariusPower обмеження розміру - це розмір масиву, і він може бути більше 255. Ви просто не можете надати endIndexбільший розмір масиву, переданого як перший аргумент. Отже, якщо ви хочете повну копію, створіть змінну, що посилається на цей масив, та використовуйте Arrays.copyOfRange(var, 0, var.length)абоArrays.copyOf(var, var.length)
elias

Я мав би створити локальний var для масиву stacktrace, але я виявив, що це працює !!! Arrays.copyOfRange(Thread.currentThread().getStackTrace(),1,Short.MAX_VALUE)
Сила Водолія

Будьте уважні ArrayIndexOutOfBoundsException.
elias

1
є ще одна проблема. Що робити, якщо мені потрібно розділити рядковий масив довжиною, скажімо, 500K на підриси 250K. Цей метод приймає інтерегр, максимум на 65000.
Вішну Дахатонде

31

Ви можете обернути свій масив як список і подати запит на його список.

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

22

Так, ви можете використовувати Arrays.copyOfRange

Це приблизно те ж саме (зауважте, що є копія: ви не змінюєте початковий масив).


2
Це означає, що якщо ви не хочете робити явну копію, вам потрібно буде використовувати а Listта а, subListяк зазначено у відповіді @ K-bal.
Луї Вассерман

Це вірно. У Java немає засобів для нарізки масивів, які пропонують більш сучасні мови.
Denys Séguret

Я не впевнений, чи сказав би я так, але ... так, Java не пропонує нарізки масивів. (Це означає, що в цьому підході є деякі переваги: ​​зменшення можливостей для витоку пам'яті, зменшення накладних масивів, уникаючи зайвих полів тощо. Ви можете піти в будь-який бік.)
Луї Васерман,

Так, ти знову правий (і я не намагався розпочати війну полум'я;)). Нарізання робить GC дуже складним. І коли Java спробувала неявне нарізання на основі об'єкта, це зробило більш очевидним, що це небезпечно .
Denys Séguret

11

Ви можете спробувати:

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); 

Дивіться javadoc для System .


3
Мені просто подобається, як це саме так, як Arrays.copyOf () і Arrays.copyOfRange () реально реалізовані (не перевіряє межі перевірки), і все ж вона не отримує голосів, хоча трохи більш високі накладні способи обгортки набирають голоси, незважаючи на знайомства з System.arraycopy назад у 1995.
Дейв

1
Я думаю, це просто не виглядає достатньо сучасним для деяких.
Дейв

Мені подобається ходити в стару школу, без блискучих дзвіночків і просто свистків потрібна техніка. Як memcpy в C
StvnBrkdll

Але використання arrays.copyOfRange () збільшує читабельність та значно зменшує можливість появи помилок.
Флоріан Ф

7

Якщо ви використовуєте Java 1.6 або новішої версії, ви можете Arrays.copyOfRangeскопіювати частину масиву. Від javadoc:

Копіює вказаний діапазон вказаного масиву в новий масив. Початковий показник діапазону (від) повинен лежати між нулем і original.lengthвключно. Значення при original[from]поміщається в початковий елемент копії (якщо from == original.lengthабо from == to). Значення наступних елементів у вихідному масиві розміщуються на наступні елементи в копії. Кінцевий індекс діапазону ( to), який повинен бути більшим або рівним from, може бути більшим, ніж original.lengthу цьому випадку falseрозміщується у всіх елементах копії, індекс яких більший або дорівнює original.length - from. Довжина повернутого масиву буде to - from.

Ось простий приклад :

/**
 * @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

Ви можете використовувати subList(int fromIndex, int toIndex)метод у цілому arr, приблизно так:

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 + " ");
    }
}

Вихід буде: 2 3.

Зауважте, що subList(int fromIndex, int toIndex)метод виконує мінус 1 на 2-й змінній, яку він отримує (var2 - 1), я не знаю точно чому, але саме так трапляється, можливо, щоб зменшити шанс перевищення розміру масиву.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.