Obtenir seulement une partie d'un tableau en Java?

275

J'ai un tableau d'entiers en Java, je voudrais en utiliser seulement une partie. Je sais qu'en Python, vous pouvez faire quelque chose comme ce tableau [index:] et il renvoie le tableau de l'index. Est-ce quelque chose comme ça possible en Java.

Borut Flis
la source

Réponses:

444

La longueur d'un tableau en Java est immuable. Vous devez donc copier la partie souhaitée en tant que nouveau tableau.
Utilisez la copyOfRangeméthode de la classe java.util.Arrays :

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

startIndex est l'index initial de la plage à copier, inclus.
endIndex est l'index final de la plage à copier, exclusif. (Cet index peut se trouver en dehors du tableau)

Par exemple:

   //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
la source
il semble y avoir une limite de taille? cela fonctionne seulement: Arrays.copyOfRange(Thread.currentThread().getStackTrace(),1,255)comme au lieu de 255, je ne peux pas utiliser Integer.MAX_VALUE, au cas où je ne voudrais pas obtenir la longueur réelle
Aquarius Power
@AquariusPower la limite de taille est la taille du tableau, et elle peut être supérieure à 255. Vous ne pouvez tout simplement pas fournir un endIndexplus grand que la taille du tableau passé comme premier argument. Donc, si vous voulez une copie complète, créez une variable faisant référence à ce tableau et utilisez Arrays.copyOfRange(var, 0, var.length)ouArrays.copyOf(var, var.length)
elias
Je devrais créer un var local pour le sous-tableau stacktrace, mais j'ai trouvé que cela fonctionne !!! Arrays.copyOfRange(Thread.currentThread().getStackTrace(),1,Short.MAX_VALUE)
Aquarius Power
Soyez prudent ArrayIndexOutOfBoundsException.
elias
1
il y a un autre problème. Et si j'ai besoin de diviser le tableau de chaînes de longueur, disons 500K en sous-réseaux de 250K. Cette méthode accepte un intergr qui qui max à 65000.
Vishnu Dahatonde
31

Vous pouvez envelopper votre tableau sous forme de liste et en demander une sous-liste.

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

Oui, vous pouvez utiliser Arrays.copyOfRange

Il fait à peu près la même chose (notez qu'il y a une copie: vous ne changez pas le tableau initial).

Denys Séguret
la source
2
Cela dit, si vous ne voulez pas faire de copie explicite, vous devrez utiliser un Listet un subListcomme indiqué dans la réponse de @ K-ballo.
Louis Wasserman
C'est vrai. Java ne dispose pas des fonctionnalités de découpage de baie que les langages plus modernes offrent.
Denys Séguret
Je ne sais pas si je l'aurais dit de cette façon, mais ... oui, Java n'offre pas de découpage de tableau. (Cela dit, cette approche présente certains avantages: possibilités réduites de fuites de mémoire, réduction de la surcharge de la baie en évitant les champs supplémentaires, etc. Vous pouvez aller dans les deux sens.)
Louis Wasserman
Oui, vous avez raison (et je n'ai pas essayé de déclencher une guerre des flammes;)). Le tranchage rend le GC très complexe. Et lorsque Java a essayé le découpage implicite basé sur des objets dans Strings, il est devenu plus évident que c'était dangereux .
Denys Séguret
11

Tu peux essayer:

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

Voir javadoc pour System .

StvnBrkdll
la source
3
J'adore la façon dont c'est exactement la façon dont Arrays.copyOf () et Arrays.copyOfRange () sont réellement implémentées (vérifications sans limites) et pourtant il n'obtient aucun vote tandis que les wrappers de la méthode utilitaire de surcharge légèrement plus élevés accumulent les votes malgré la datation System.arraycopy retour à 1995.
Dave
1
Je suppose que cela ne semble pas assez "moderne" pour certains.
Dave
J'aime aller à la vieille école, pas de cloches et de sifflets brillants juste la machinerie requise. Comme memcpy dans C
StvnBrkdll
Mais l'utilisation de arrays.copyOfRange () augmente la lisibilité et réduit considérablement les risques de bogues.
Florian F
7

Si vous utilisez Java 1.6 ou supérieur, vous pouvez utiliser Arrays.copyOfRangepour copier une partie du tableau. Du javadoc:

Copie la plage spécifiée du tableau spécifié dans un nouveau tableau. L'index initial de la plage (de) doit être compris entre zéro et original.length, inclus. La valeur at original[from]est placée dans l'élément initial de la copie (sauf si from == original.lengthou from == to). Les valeurs des éléments suivants du tableau d'origine sont placées dans les éléments suivants de la copie. L'index final de la plage ( to), qui doit être supérieur ou égal à from, peut être supérieur à original.length, auquel cas il falseest placé dans tous les éléments de la copie dont l'index est supérieur ou égal à original.length - from. La longueur du tableau retourné sera to - from.

Voici un exemple 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
la source
3

Découvrez copyOfRange ; et exemple:

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

Vous pouvez utiliser la subList(int fromIndex, int toIndex)méthode sur vos entiers arr, quelque chose comme ceci:

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

Sortie sera: 2 3.

Notez que la subList(int fromIndex, int toIndex)méthode effectue moins 1 sur la 2ème variable qu'elle reçoit (var2 - 1), je ne sais pas exactement pourquoi, mais c'est ce qui se passe, peut-être pour réduire le risque de dépasser la taille du tableau.

A. Ab
la source