Obter apenas parte de uma matriz em Java?

275

Eu tenho uma matriz de números inteiros em Java, gostaria de usar apenas uma parte dele. Eu sei que em Python você pode fazer algo como esse array [index:] e ele retorna o array do índice. É algo como isso possível em Java.

Borut Flis
fonte

Respostas:

444

O comprimento de uma matriz em Java é imutável. Portanto, você precisa copiar a parte desejada como uma nova matriz.
Use o copyOfRangemétodo da classe java.util.Arrays :

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

startIndex é o índice inicial do intervalo a ser copiado, inclusive.
endIndex é o índice final do intervalo a ser copiado, exclusivo. (Esse índice pode estar fora da matriz)

Por exemplo:

   //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)
elias
fonte
parece haver um limite de tamanho? apenas isso funciona: Arrays.copyOfRange(Thread.currentThread().getStackTrace(),1,255)como, em vez de 255 I não pode usar Integer.MAX_VALUE, no caso de eu não quero obter o comprimento real
Aquarius Energia
@AquariusPower, o limite de tamanho é o tamanho da matriz e pode ser maior que 255. Você simplesmente não pode fornecer um endIndextamanho maior que o tamanho da matriz passado como o primeiro argumento. Portanto, se você quiser uma cópia completa, crie uma variável referente a essa matriz e use Arrays.copyOfRange(var, 0, var.length)orArrays.copyOf(var, var.length)
elias
Eu teria que criar um var local para o subtrace stacktrace, mas achei que isso funciona !!! Arrays.copyOfRange(Thread.currentThread().getStackTrace(),1,Short.MAX_VALUE)
Poder de Aquário
Tenha cuidado com ArrayIndexOutOfBoundsException.
elias
1
existe outro problema. E se eu precisar dividir o conjunto de cadeias de comprimento, digamos 500K nos subarrays de 250K. Estes método aceita interegr que máximo para fora em 65000.
Vishnu Dahatonde
31

Você pode agrupar sua matriz como uma lista e solicitar uma sub-lista dela.

MyClass[] array = ...;
List<MyClass> subArray = Arrays.asList(array).subList(index, array.length);
K-ballo
fonte
22

Sim, você pode usar Arrays.copyOfRange

Faz a mesma coisa (observe que há uma cópia: você não altera a matriz inicial).

Denys Séguret
fonte
2
Dito isto, se você não quiser fazer uma cópia explícita, precisará usar um Liste um, subListconforme descrito na resposta do @ K-ballo.
Louis Wasserman
Está certo. Java não possui os recursos de divisão de matriz que as linguagens mais modernas oferecem.
Denys Séguret
Não tenho certeza se eu colocaria dessa maneira, mas ... sim, Java não oferece fatia de matriz. (Dito isto, existem algumas vantagens para esta abordagem: redução de possibilidades de vazamentos de memória, variedade reduzidos cima, evitando os campos extras, etc. Você poderia ir de qualquer maneira.)
Louis Wasserman
Sim, você está certo novamente (e eu não tentei iniciar uma guerra de chamas;)). A fatia torna o GC muito complexo. E quando o Java tentou fatiar implícito com base em objetos no Strings , ficou mais evidente que isso era perigoso .
Denys Séguret
11

Podes tentar:

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

Veja javadoc para System .

StvnBrkdll
fonte
3
Eu simplesmente amo como isso é exatamente como Arrays.copyOf () e Arrays.copyOfRange () são realmente implementados (verificações sem limites) e, no entanto, não obtém votos, enquanto os wrappers de método de utilitário de sobrecarga um pouco mais altos acumulam os votos, apesar do namoro System.arraycopy de volta a 1995.
Dave
1
Eu acho que apenas não parece "moderno" o suficiente para alguns.
Dave
Eu gosto de ir à velha escola, sem sinos e assobios brilhantes apenas as máquinas necessárias. Como memcpy em C
StvnBrkdll 23/04
Mas o uso de arrays.copyOfRange () aumenta a legibilidade e reduz significativamente a possibilidade de erros.
Florian F
7

Se você estiver usando o Java 1.6 ou superior, poderá Arrays.copyOfRangecopiar uma parte da matriz. Do javadoc:

Copia o intervalo especificado da matriz especificada para uma nova matriz. O índice inicial do intervalo (de) deve estar entre zero e original.length, inclusive. O valor em original[from]é colocado no elemento inicial da cópia (a menos que from == original.lengthou from == to). Os valores dos elementos subseqüentes na matriz original são colocados nos elementos subseqüentes na cópia. O índice final do intervalo ( to), que deve ser maior ou igual a from, pode ser maior que original.length, nesse caso, falseé colocado em todos os elementos da cópia cujo índice é maior ou igual a original.length - from. O comprimento da matriz retornada será to - from.

Aqui está um exemplo simples :

/**
 * @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]);
    }

}
Justin Ethier
fonte
3

Confira copyOfRange ; e exemplo:

int[] arr2 = Arrays.copyOfRange(arr,0,3);
dcp
fonte
-2

Você pode usar o subList(int fromIndex, int toIndex)método em seus números inteiros, algo como isto:

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

Saída será: 2 3.

Observe que o subList(int fromIndex, int toIndex)método executa menos 1 na 2ª variável que recebe (var2 - 1), não sei exatamente por que, mas é o que acontece, talvez para reduzir a chance de exceder o tamanho da matriz.

A. Ab
fonte