Получить только часть массива в 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);
K-Балло
источник
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 для системы .

StvnBrkdll
источник
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), я точно не знаю, почему, но именно это и происходит, возможно, чтобы уменьшить вероятность превышения размера массива.

А. Аб
источник