Como criar uma sub-matriz de outra matriz em Java?


284

Como criar uma sub-matriz de outra matriz? Existe um método que utiliza os índices da primeira matriz, como:

methodName(object array, int start, int end)

Não quero deixar de fazer loops e fazer meu programa sofrer.

Eu continuo recebendo erro:

não é possível encontrar o método de símbolo copyOfRange (int [], int, int)

Este é o meu 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);
    }
}

Respostas:


305

Você pode 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
Eu estava tendo alguns problemas por não ter Object [] s em meu Arrays.copyOfRange. Verifique suas importações para garantir que você esteja usando java.util.Arrays. De alguma forma, uma versão diferente do Arrays foi importada e eu perdi 15 minutos verificando JREs e JDKs quanto ao problema.
NuclearPeon

@NuclearPeon Thank you !!! Teria me levado muito tempo antes que eu descobrisse. Eclipse importado automaticamente org.bouncycastle.util.Arrays.
21717 Anddero

136

Arrays.copyOfRange(..)foi adicionado no Java 1.6. Talvez você não tenha a versão mais recente. Se não for possível atualizar, vejaSystem.arraycopy(..)


1
O @Sami atualiza para a versão 1.6 ou consulte este documento para obter a referência download.oracle.com/javase/1.4.2/docs/api/java/lang/System.html
Jigar Joshi

4
De qual fornecedor é o seu JDK. A Sun / Oracle nunca lançou a versão 4.00.28 e o Google também não conseguiu encontrá-la.
Peter Lawrey

copyOfRange nulls fuga elementos se eles estão fora do intervalo da matriz de origem em vez de atribuir uma matriz menor :(
Daneel S. Yaitskov

12
alguém deve adicionar na resposta que enquanto "start-index" é inclusivo, "end-index" é exclusivo
Yan rei Yin

@YanKingYin você está correto - este é precisamente o que eu estava lendo os comentários para :)
Ben Kushigian


20

Sim, é chamado System.arraycopy (Object, int, Object, int, int) .

No entanto, ele ainda executará um loop em algum lugar, a menos que isso possa ser otimizado para algo como REP STOSWo JIT (nesse caso, o loop está dentro da 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 o Apache ArrayUtils para download neste link, você pode usar facilmente o método

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

"boolean" é apenas um exemplo, existem métodos para todos os tipos java primitivos


6

JDK> = 1,8

Eu concordo com todas as respostas acima. Há também uma boa maneira com o Java 8 Streams:

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

O benefício disso é que ele pode ser útil para muitos tipos diferentes de matriz "src" e ajuda a melhorar as operações de gravação de pipeline no fluxo.

Não é específico sobre esta questão, mas, por exemplo, se a matriz de origem era double[]e desejávamos tirar average()da 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

O código está correto, então acho que você está usando um JDK mais antigo. O javadoc para esse método diz que existe desde a versão 1.6. Na linha de comando, digite:

java -version

Eu estou supondo que você não está executando o 1.6


1

Se você estiver usando java antes da versão 1.6, use System.arraycopy(). Ou atualize seu ambiente.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.