¿Obtener solo una parte de una matriz en Java?

275

Tengo una matriz de enteros en Java, me gustaría usar solo una parte de ella. Sé que en Python puedes hacer algo como esta matriz [index:] y devuelve la matriz del índice. Es posible algo así en Java.

Borut Flis
fuente

Respuestas:

444

La longitud de una matriz en Java es inmutable. Por lo tanto, debe copiar la parte deseada como una nueva matriz.
Utilice el copyOfRangemétodo de la clase java.util.Arrays :

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

startIndex es el índice inicial del rango que se copiará, inclusive.
endIndex es el índice final del rango a copiar, exclusivo. (Este índice puede estar fuera de la matriz)

P.ej:

   //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
fuente
parece haber un límite de tamaño? solo esto funciona: Arrays.copyOfRange(Thread.currentThread().getStackTrace(),1,255)como en lugar de 255 no puedo usar Integer.MAX_VALUE, en caso de que no quiera obtener la longitud real
Aquarius Power
@AquariusPower el límite de tamaño es el tamaño de la matriz, y puede ser mayor que 255. Simplemente no puede proporcionar un endIndextamaño mayor que la matriz aprobada como primer argumento. Entonces, si desea una copia completa, cree una variable que se refiera a esta matriz y use Arrays.copyOfRange(var, 0, var.length)oArrays.copyOf(var, var.length)
elias el
Tendría que crear una var local para la matriz secundaria stacktrace, ¡pero descubrí que esto funciona! Arrays.copyOfRange(Thread.currentThread().getStackTrace(),1,Short.MAX_VALUE)
Acuario Power
Tenga cuidado sobre ArrayIndexOutOfBoundsException.
elias
1
Hay otro problema. ¿Qué pasa si necesito dividir el conjunto de cadenas de longitud, digamos 500K en las submatrices de 250K? Este método acepta interegr que alcanza un máximo de 65000.
Vishnu Dahatonde
31

Puede ajustar su matriz como una lista y solicitar una sublista de la misma.

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

Sí, puedes usar Arrays.copyOfRange

Hace casi lo mismo (tenga en cuenta que hay una copia: no cambia la matriz inicial).

Denys Séguret
fuente
2
Dicho esto, si usted no quiere hacer una copia explícita, tendrá que utilizar una Listy subListcomo se indica en la respuesta de @ K-ballo.
Louis Wasserman
Así es. Java no tiene las funciones de corte de matriz que ofrecen los lenguajes más modernos.
Denys Séguret
No estoy seguro de si lo diría de esa manera, pero ... sí, Java no ofrece segmentación de matrices. (Dicho esto, hay algunas ventajas en este enfoque: posibilidades reducidas de pérdidas de memoria, reducción de la sobrecarga de la matriz al evitar los campos adicionales, etc. Podría ir en cualquier dirección).
Louis Wasserman
Sí, tienes razón de nuevo (y no intenté iniciar una guerra de llamas;)). Rebanar hace que GC sea muy complejo. Y cuando Java intentó el corte implícito basado en objetos en Strings , hizo más evidente que esto era peligroso .
Denys Séguret
11

Puedes probar:

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

Ver javadoc para Sistema .

StvnBrkdll
fuente
3
Me encanta cómo es esto exactamente cómo Arrays.copyOf () y Arrays.copyOfRange () se implementan realmente (sin controles de límites) y, sin embargo, no obtiene votos, mientras que los envoltorios de métodos de utilidad de gastos generales ligeramente más altos acumulan los votos a pesar de la datación de System.arraycopy volver a 1995.
Dave
1
Supongo que no parece lo suficientemente "moderno" para algunos.
Dave
Me gusta ir a la vieja escuela, sin campanas y silbatos brillantes, solo la maquinaria requerida. Como memcpy en C
StvnBrkdll
Pero el uso de arrays.copyOfRange () aumenta la legibilidad y reduce significativamente la posibilidad de errores.
Florian F
7

Si está utilizando Java 1.6 o superior, puede usar Arrays.copyOfRangepara copiar una parte de la matriz. Desde el javadoc:

Copia el rango especificado de la matriz especificada en una nueva matriz. El índice inicial del rango (desde) debe estar entre cero e original.lengthinclusive. El valor en original[from]se coloca en el elemento inicial de la copia (a menos que from == original.lengtho from == to). Los valores de elementos posteriores en la matriz original se colocan en elementos posteriores en la copia. El índice final del rango ( to), que debe ser mayor o igual que from, puede ser mayor que original.length, en cuyo caso falsese coloca en todos los elementos de la copia cuyo índice es mayor o igual que original.length - from. La longitud de la matriz devuelta será to - from.

Aquí hay un ejemplo simple :

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

Echa un vistazo a copyOfRange ; y ejemplo:

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

Puede usar el subList(int fromIndex, int toIndex)método en sus enteros arr, algo como esto:

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

La salida será: 2 3.

Tenga en cuenta que el subList(int fromIndex, int toIndex)método realiza menos 1 en la segunda variable que recibe (var2 - 1), no sé exactamente por qué, pero eso es lo que sucede, tal vez para reducir la posibilidad de exceder el tamaño de la matriz.

A. Ab
fuente