¿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);
    }
}
Ganancia
fuente

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

Jigar Joshi
fuente
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(..)

Bozho
fuente
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
43

Utilice el método copyOfRange de la clase java.util.Arrays:

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

Para más detalles:

Enlace a pregunta similar

Dhirendra Pratap
fuente
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
Gerco Dries
fuente
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

Alessandro Muzzi
fuente
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();
enator
fuente
3
int newArrayLength = 30; 

int[] newArray = new int[newArrayLength];

System.arrayCopy(oldArray, 0, newArray, 0, newArray.length);
Milan Jaros
fuente
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

Merky
fuente
1

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

AlexR
fuente