Получить только часть массива в Java?


275

У меня есть массив целых чисел в 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, в случае, если я не хочу получать реальную длину
— Aquarius Power

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

Я должен был бы создать локальную переменную для подмассива stacktrace, но я обнаружил, что это работает !!! Arrays.copyOfRange(Thread.currentThread().getStackTrace(),1,Short.MAX_VALUE)
— Водолей Сила

Будьте осторожны ArrayIndexOutOfBoundsException.
— Элиас

1
есть другая проблема. Что делать, если мне нужно разбить строковый массив длиной, скажем, 500 КБ на подмассивы 250 КБ. Этот метод принимает interegr, который максимально на 65000.
— Вишну Дахатонд

31

Вы можете заключить свой массив в список и запросить его подсписок.

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

22

Да, вы можете использовать Arrays.copyOfRange

Это делает примерно то же самое (обратите внимание, что есть копия: вы не меняете исходный массив).


2
Тем не менее, если вы не хотите делать явную копию, вам нужно использовать a Listи a, subListкак указано в ответе @ K-bal.
— Луи Вассерман

Это правильно. Java не имеет средств нарезки массивов, которые предлагают более современные языки.
— Денис Сегюре

Я не уверен, если бы я сказал так, но ... да, Java не предлагает нарезку массивов. (Тем не менее, у этого подхода есть некоторые преимущества: уменьшенные возможности для утечек памяти, уменьшенные накладные расходы массива за счет исключения лишних полей и т. Д. Вы можете пойти любым путем.)
— Луи Вассерман

Да, вы снова правы (и я не пытался начать пламенную войну;)). Нарезка делает GC очень сложным. И когда Java попробовала неявную нарезку на основе объектов в строках, это сделало более очевидным, что это опасно .
— Денис Сегюре

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 для системы .


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). Значения из последующих элементов в исходном массиве помещаются в последующие элементы в копии. Окончательный индекс range ( 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.