¿Cómo crear una submatriz a partir de otra matriz en Java?


284

¿Cómo crear una submatriz a partir de otra matriz? ¿Hay algún método que tome los índices de la primera matriz como:

methodName(object array, int start, int end)

No quiero volver a hacer bucles y hacer que mi programa sufra.

Sigo recibiendo errores:

no se puede encontrar el método de símbolo copyOfRange (int [], int, int)

Este es mi código:

import java.util.*;

public class testing 
{
    public static void main(String [] arg) 
    {   
        int[] src = new int[] {1, 2, 3, 4, 5}; 
        int b1[] = Arrays.copyOfRange(src, 0, 2);
    }
}

Respuestas:


305

Puedes usar

JDK> 1.5

Arrays.copyOfRange(Object[] src, int from, int to)

Javadoc

JDK <= 1.5

System.arraycopy(Object[] src, int srcStartIndex, Object[] dest, int dstStartIndex, int lengthOfCopiedIndices); 

Javadoc


3
Estaba teniendo algunos problemas al no tener Object [] s en mi Arrays.copyOfRange. Verifique sus importaciones para asegurarse de que está utilizando java.util.Arrays. De alguna manera, se importó una versión diferente de Arrays y perdí 15 minutos buscando el problema en JRE y JDK.
— NuclearPeon

@NuclearPeon ¡Gracias! Me hubiera llevado mucho tiempo antes de que me diera cuenta. Eclipse importado automáticamente org.bouncycastle.util.Arrays.
— anddero

136

Arrays.copyOfRange(..)fue agregado en Java 1.6. Entonces quizás no tienes la última versión. Si no es posible actualizar, miraSystem.arraycopy(..)


1
@Sami puede actualizar a 1.6 o ver este documento como referencia download.oracle.com/javase/1.4.2/docs/api/java/lang/System.html
— Jigar Joshi

44
¿De qué proveedor es su JDK? Sun / Oracle nunca lanzó una versión 4.00.28 y Google tampoco pudo encontrarla.
— Peter Lawrey

copyOfRange anula los elementos finales si están fuera del rango de la matriz de origen en lugar de asignar una matriz más pequeña :(
— Daneel S. Yaitskov

12
alguien debería agregar la respuesta de que si bien "start-index" es inclusivo, "end-index" es exclusivo
— Yan King Yin

@YanKingYin tienes razón: esto es precisamente para lo que estaba leyendo los comentarios :)
— Ben Kushigian


20

Sí, se llama System.arraycopy (Object, int, Object, int, int) .

Sin embargo, seguirá ejecutando un bucle en alguna parte, a menos que REP STOSWel JIT pueda optimizarlo en algo así (en cuyo caso el bucle está dentro de la CPU).

int[] src = new int[] {1, 2, 3, 4, 5};
int[] dst = new int[3];

System.arraycopy(src, 1, dst, 0, 3); // Copies 2, 3, 4 into dst

7

Usando Apache ArrayUtils descargable en este enlace , puede usar fácilmente el método

subarray(boolean[] array, int startIndexInclusive, int endIndexExclusive) 

"boolean" es solo un ejemplo, hay métodos para todos los tipos primitivos de Java


6

JDK> = 1.8

Estoy de acuerdo con todas las respuestas anteriores. También hay una buena manera con Java 8 Streams:

int[] subArr = IntStream.range(startInclusive, endExclusive)
                        .map(i -> src[i])
                        .toArray();

El beneficio de esto es que puede ser útil para muchos tipos diferentes de matriz "src" y ayuda a mejorar las operaciones de canalización de escritura en la secuencia.

No es particular acerca de esta pregunta, pero por ejemplo, si la matriz fuente era double[]y queríamos tomar average()la sub-matriz:

double avg = IntStream.range(startInclusive, endExclusive)
                    .mapToDouble(index -> src[index])
                    .average()
                    .getAsDouble();

3
int newArrayLength = 30; 

int[] newArray = new int[newArrayLength];

System.arrayCopy(oldArray, 0, newArray, 0, newArray.length);

2

El código es correcto, así que supongo que está utilizando un JDK anterior. El javadoc para ese método dice que ha estado allí desde 1.6. En la línea de comando escriba:

java -version

Supongo que no estás ejecutando 1.6


1

En su lugar, está utilizando Java antes de la versión 1.6 System.arraycopy(). O actualice su entorno.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.