Comment convertir un tableau d'objets en tableau de chaînes en Java

244

J'utilise le code suivant pour convertir un tableau d'objets en un tableau de chaînes:

Object Object_Array[]=new Object[100];
// ... get values in the Object_Array

String String_Array[]=new String[Object_Array.length];

for (int i=0;i<String_Array.length;i++) String_Array[i]=Object_Array[i].toString();

Mais je me demande s'il y a une autre façon de procéder, quelque chose comme:

String_Array=(String[])Object_Array;

Mais cela provoquerait une erreur d'exécution: Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String;

Quelle est la bonne façon de procéder?

Franc
la source
3
J'aime mieux la réponse de waxwing: String [] stringArray = Arrays.copyOf (objectArray, objectArray.length, String []. Class); C'est très concis et ça marche. J'ai compté combien de temps cela prend pour sa réponse et mon approche actuelle, ils sont à peu près les mêmes.
Frank

Réponses:

381

Une autre alternative à System.arraycopy:

String[] stringArray = Arrays.copyOf(objectArray, objectArray.length, String[].class);
jaseur
la source
59
uniquement sur Java 1.6 et supérieur
newacct
10
Hrm. Je n'ai pas réussi à faire fonctionner celui-ci, où l'exemple long dans la question d'origine fonctionne. Il lève java.lang.ArrayStoreException. J'obtiens le tableau d'objets de la méthode toArray sur un ArrayList générique contenant mon type personnalisé. N'est-ce pas censé fonctionner avec des génériques ou quelque chose?
Ian Varley
4
@Ian, le problème est que objectArray contient des objets et non des chaînes (voir le commentaire de mmyers à ma réponse qui souffre du même problème).
Yishai
3
Je viens d'essayer cette approche et, au moins dans mon cas, j'ai découvert que les performances ne sont pas aussi bonnes que la création du tableau moi-même en itérant. (Dommage cependant, je l'ai aimé en
monoplace
1
@mdup - assez long one liner. envelopper peut-être dans une méthode.
MasterJoe2
72

En Java 8:

String[] strings = Arrays.stream(objects).toArray(String[]::new);

Pour convertir un tableau d'autres types:

String[] strings = Arrays.stream(obj).map(Object::toString).
                   toArray(String[]::new);
Vitalii Fedorenko
la source
2
Ceci est un travail de beauté et répond à l'exigence de pouvoir convertir esthétiquement un tableau d'objets non-String en un tableau de leurs équivalents toString. La réponse actuellement acceptée n'y parvient pas.
b4n4n4p4nd4
Cela fonctionne, mais si votre liste contient des valeurs nulles, vous obtiendrez une exception NullPointerException. Pour contourner ce problème, voir: stackoverflow.com/questions/4581407/…
Tony Falabella
61

System.arraycopy est probablement le moyen le plus efficace, mais pour l'esthétique, je préfère:

 Arrays.asList(Object_Array).toArray(new String[Object_Array.length]);
Yishai
la source
10
Cela ne fonctionne que si les objets sont tous des chaînes; son code actuel fonctionne même si ce n'est pas le cas.
Michael Myers
Bon point. J'ai compris que le toString n'était qu'un moyen de transtyper en chaîne, et non pas l'intention de remplacer réellement les objets par autre chose. Si c'est ce que vous devez faire, le bouclage est le seul moyen.
Yishai
cela ne fonctionne pas dans Android 2.3.3 .. cela me donne une erreur disant que la méthode copyof n'est pas définie. J'ai importé tous les bons fichiers (ctrl + shift + I) .. mais cela ne fonctionne toujours pas.
user590849
3
@ user590849, ma réponse n'utilise pas copyof. Référez-vous à une autre réponse?
Yishai
50

Je vois que certaines solutions ont été fournies mais pas de cause, je vais donc expliquer cela en détail car je pense qu'il est aussi important de savoir ce que vous faisiez de mal que juste pour obtenir "quelque chose" qui fonctionne à partir des réponses données.

Voyons d'abord ce qu'Oracle a à dire

 * <p>The returned array will be "safe" in that no references to it are
 * maintained by this list.  (In other words, this method must
 * allocate a new array even if this list is backed by an array).
 * The caller is thus free to modify the returned array.

Cela peut ne pas sembler important, mais comme vous le verrez, alors ... Qu'est-ce que la ligne suivante échoue? Tous les objets de la liste sont String mais il ne les convertit pas, pourquoi?

List<String> tList = new ArrayList<String>();
tList.add("4");
tList.add("5");
String tArray[] = (String[]) tList.toArray();   

Beaucoup d'entre vous penseraient probablement que ce code fait de même, mais ce n'est pas le cas.

Object tSObjectArray[] = new String[2];
String tStringArray[] = (String[]) tSObjectArray;

Quand en réalité le code écrit fait quelque chose comme ça. Le javadoc le dit! Il va créer un nouveau tableau, ce que ce sera des objets !!!

Object tSObjectArray[] = new Object[2];
String tStringArray[] = (String[]) tSObjectArray;   

Donc, tList.toArray instancie un objet et non une chaîne ...

Par conséquent, la solution naturelle qui n'a pas été mentionnée dans ce fil, mais c'est ce que recommande Oracle est la suivante

String tArray[] = tList.toArray(new String[0]);

J'espère que c'est assez clair.

Capagris
la source
Légère correction en termes de performances: String tArray [] = tList.toArray (new String [tList.size ()]); Sinon, le tableau doit être redimensionné à nouveau ...
Lonzak
1
Bonne explication. Encore une chose, si la consommation de mémoire ou les performances sont un problème, ne dupliquez pas la baie. Soit vous convertissez un élément en String chaque fois que vous en avez besoin, (String)Object_Array[i]soit vous Object_Array[i].toString()allouez le tableau en tant que tableau String Object Object_Array[]=new String[100];... obtenez des valeurs ... puis transformez String_Array=(String[])Object_Arrayce qui fonctionne maintenant.
Solostaran14
1
cela lève ArrayStoreException
iltaf khalid
7

Le cadre des collections Google propose de citer une bonne méthode de transformation, afin que vous puissiez transformer vos objets en chaînes. Le seul inconvénient est que cela doit être de Iterable à Iterable mais c'est la façon dont je le ferais:

Iterable<Object> objects = ....... //Your chosen iterable here
Iterable<String> strings = com.google.common.collect.Iterables.transform(objects, new Function<Object, String>(){
        String apply(Object from){
             return from.toString();
        }
 });

Cela vous éloigne de l'utilisation des tableaux, mais je pense que ce serait ma façon préférée.

Richard
la source
1
@Yishai: non, les tableaux n'implémentent pas Iterable. l'itération sur eux est spécialement définie dans le JLS
newacct
@newacct, tout à fait vrai, je voulais dire que les tableaux peuvent être facilement enveloppés dans un Iterable (Arrays.asList ()). Je ne sais pas pourquoi c'est sorti comme ça.
Yishai
5

Si vous souhaitez obtenir une représentation String des objets de votre tableau, alors oui, il n'y a pas d'autre moyen de le faire.

Si vous savez que votre tableau d'objets contient uniquement des chaînes, vous pouvez également le faire (au lieu d'appeler toString ()):

for (int i=0;i<String_Array.length;i++) String_Array[i]= (String) Object_Array[i];

Le seul cas où vous pourriez utiliser le transtypage en String [] de Object_Array serait si le tableau auquel il fait référence était réellement défini comme String [], par exemple, cela fonctionnerait:

    Object[] o = new String[10];
    String[] s = (String[]) o;
david a.
la source
5

Celui-ci est agréable, mais ne fonctionne pas comme l'ont remarqué mmyers, à cause des crochets:

Arrays.toString(objectArray).split(",")

Celui-ci est moche mais fonctionne:

Arrays.toString(objectArray).replaceFirst("^\\[", "").replaceFirst("\\]$", "").split(",")

Si vous utilisez ce code, vous devez être sûr que les chaînes retournées par toString () de vos objets ne contiennent pas de virgules.

Ilya Boyandin
la source
1
Suggestion intéressante, mais vous devez d'abord supprimer le [et] du premier et du dernier élément.
Michael Myers
1
magnifique jusqu'à ce qu'il accomplisse le travail :)
AZ_
2
Cela ne fonctionne pas si une chaîne contient une virgule (,)
Andreas Berger
2

Pour votre idée, en fait, vous approchez du succès, mais si vous aimez cela, ça devrait aller:

for (int i=0;i<String_Array.length;i++) String_Array[i]=(String)Object_Array[i];

BTW, en utilisant la méthode utilitaire Arrays est assez bon et rend le code élégant.

ttt
la source
1
Object arr3[]=list1.toArray();
   String common[]=new String[arr3.length];

   for (int i=0;i<arr3.length;i++) 
   {
   common[i]=(String)arr3[i];
  }
Amit Kumar Sagar
la source
1

Vous pouvez utiliser un convertisseur de type . Pour convertir un tableau de n'importe quel type en tableau de chaînes, vous pouvez enregistrer votre propre convertisseur:

 TypeConverter.registerConverter(Object[].class, String[].class, new Converter<Object[], String[]>() {

        @Override
        public String[] convert(Object[] source) {
            String[] strings = new String[source.length];
            for(int i = 0; i < source.length ; i++) {
                strings[i] = source[i].toString();
            }
            return strings;
        }
    });

et l'utiliser

   Object[] objects = new Object[] {1, 23.43, true, "text", 'c'};
   String[] strings = TypeConverter.convert(objects, String[].class);
lstypka
la source
0

Changez facilement sans aucun headche Convertissez n'importe quel tableau d'objets en tableau de chaînes Object drivex [] = {1,2};

    for(int i=0; i<drive.length ; i++)
        {
            Str[i]= drivex[i].toString();
            System.out.println(Str[i]); 
        }
Rahul Chhangani
la source