Une façon rapide et facile de joindre des éléments de tableau avec un séparateur (le contraire de split) En Java [dupliquer]

cette question a déjà une réponse ici:

  • Java: fonction pour les tableaux comme join () de PHP? 22 réponses

Voir "1519130920 Connexes".NET question

je cherche un moyen rapide et facile de faire exactement le contraire de split de sorte que il sera la cause de ["a","b","c"] pour devenir "a,b,c"

itérer à travers un tableau nécessite soit l'ajout d'une condition (si ce n'est pas le dernier élément, ajouter le seperateur), soit l'utilisation d'une sous-couche pour supprimer le dernier séparateur.

Je suis sûr qu'il existe un moyen certifié et efficace de le faire (Apache Commons?)

Comment préférez-vous le faire dans vos projets?

345
demandé sur Community 2009-12-30 10:38:48

15 réponses

en utilisant Java 8, Vous pouvez le faire d'une manière très propre:

String.join(delimiter, elements);

cela fonctionne de trois façons:

1 )spécifiant directement les éléments

String joined1 = String.join(",", "a", "b", "c");

2) utilisant des matrices

String[] array = new String[] { "a", "b", "c" };
String joined2 = String.join(",", array);

3) utilisant des itérables

List<String> list = Arrays.asList(array);
String joined3 = String.join(",", list);
566
répondu skiwi 2017-04-18 20:55:23

si vous êtes sur Android vous pouvez TextUtils.join(delimiter, tokens)

262
répondu nmr 2014-07-18 23:14:58

je préfère Google Collections plutôt que Apache StringUtils pour ce problème particulier:

Joiner.on(separator).join(array)

par rapport à StringUtils, L'API de menuisier a un design fluent et est un peu plus flexible, par exemple null éléments peuvent être sautés ou remplacés par un placeholder. En outre, Joiner a une caractéristique pour joindre des cartes avec un séparateur entre la clé et la valeur.

105
répondu nd. 2009-12-31 10:00:21

Apache Commons Lang a en effet un StringUtils.join la méthode qui permettra de relier les String des tableaux avec un séparateur spécifié.

par exemple:

String[] s = new String[] {"a", "b", "c"};
String joined = StringUtils.join(s, ",");  // "a,b,c"

cependant, je soupçonne que, comme vous le mentionnez, il doit y avoir une sorte de traitement conditionnel ou de substrat dans la mise en œuvre effective de la méthode mentionnée ci-dessus.

si je devais effectuer le String rejoignant et n'ayant pas d'autres raisons D'utiliser Commons Lang, Je roulerais probablement mon propre pour réduire le nombre de dépendances aux bibliothèques externes.

94
répondu coobird 2013-04-14 13:47:48

une solution simple et rapide sans aucun tiers comprend.

public static String strJoin(String[] aArr, String sSep) {
    StringBuilder sbStr = new StringBuilder();
    for (int i = 0, il = aArr.length; i < il; i++) {
        if (i > 0)
            sbStr.append(sSep);
        sbStr.append(aArr[i]);
    }
    return sbStr.toString();
}
41
répondu Zedas 2013-03-08 11:44:26

" je suis sûr qu'il existe un moyen certifié et efficace de le faire (Apache Commons?) "

Oui, apparemment c'est

StringUtils.join(array, separator)

http://www.java2s.com/Code/JavaAPI/org.apache.commons.lang/StringUtilsjoinObjectarrayStringseparator.htm

20
répondu Roland Bouman 2009-12-30 07:41:42

vous pouvez utiliser remplacer et remplacer tout avec des expressions régulières.

String[] strings = {"a", "b", "c"};

String result = Arrays.asList(strings).toString().replaceAll("(^\[|\]$)", "").replace(", ", ",");

parce que Arrays.asList().toString() produit:" [a, b, c]", nous faisons un replaceAll pour supprimer les premier et dernier crochets et puis (optionnellement) vous pouvez changer le", "séquence pour", " (votre nouveau séparateur).

Une dépouillé version (moins de caractères):

String[] strings = {"a", "b", "c"};

String result = ("" + Arrays.asList(strings)).replaceAll("(^.|.$)", "").replace(", ", "," );

les expressions régulières sont très puissantes, spécialement les méthodes de chaîne de caractères "replaceFirst" et "replaceAll". De leur donner un essai.

15
répondu wadjakman 2011-11-12 18:38:12

encore plus facile vous pouvez juste utiliser des tableaux, de sorte que vous obtiendrez une chaîne avec les valeurs du tableau séparées par un ","

String concat = Arrays.toString(myArray);

donc vous finirez avec ceci: concat = "[a,b,c] "

mise à Jour

vous pouvez alors vous débarrasser des crochets en utilisant une sous-chaîne comme suggéré par Jeff

concat = concat.substring(1, concat.length() -1);

donc vous finissez avec concat = "a, b, c"

15
répondu alexm 2015-03-16 14:56:35

avec Java 1.8 il y a une nouvelle Classe StringJoiner - donc pas besoin de Guava ou Apache communes:

String str = new StringJoiner(",").add("a").add("b").add("c").toString();

ou en utilisant une collection directement avec la nouvelle api stream:

String str = Arrays.asList("a", "b", "c").stream().collect(Collectors.joining(","));
14
répondu eivindw 2015-12-01 22:33:42

toutes ces autres réponses incluent runtime overhead... comme utiliser ArrayList.toString ().replaceAll (...) qui sont très inutile.

je vais vous donner l'algorithme optimal avec zéro overhead; il ne semble pas aussi joli que les autres options, mais à l'intérieur, c'est ce qu'ils font tous (après des piles d'autres vérifications cachées, l'allocation de tableaux multiples et d'autres crud).

comme vous savez déjà que vous avez affaire à des cordes, vous pouvez enregistrer un tas d'attributions de tableaux en exécutant tout manuellement. Ce n'est pas joli, mais si vous retracez les appels de méthode réels faits par les autres implémentations, vous verrez qu'il y a le moins de dépassement d'exécution possible.

public static String join(String separator, String ... values) {
  if (values.length==0)return "";//need at least one element
  //all string operations use a new array, so minimize all calls possible
  char[] sep = separator.toCharArray();

  // determine final size and normalize nulls
  int totalSize = (values.length - 1) * sep.length;// separator size
  for (int i = 0; i < values.length; i++) {
    if (values[i] == null)
      values[i] = "";
    else
      totalSize += values[i].length();
  }

  //exact size; no bounds checks or resizes
  char[] joined = new char[totalSize];
  int pos = 0;
  //note, we are iterating all the elements except the last one
  for (int i = 0, end = values.length-1; i < end; i++) {
    System.arraycopy(values[i].toCharArray(), 0, 
      joined, pos, values[i].length());
    pos += values[i].length();
    System.arraycopy(sep, 0, joined, pos, sep.length);
    pos += sep.length;
  }
  //now, add the last element; 
  //this is why we checked values.length == 0 off the hop
  System.arraycopy(values[values.length-1].toCharArray(), 0,
    joined, pos, values[values.length-1].length());

  return new String(joined);
}
7
répondu Ajax 2012-12-14 11:59:35

cette option est rapide et claire:

  public static String join(String separator, String... values) {
    StringBuilder sb = new StringBuilder(128);
    int end = 0;
    for (String s : values) {
      if (s != null) {
        sb.append(s);
        end = sb.length();
        sb.append(separator);
      }
    }
    return sb.substring(0, end);
  }
5
répondu mnesarco 2014-05-29 17:31:52

cette petite fonction est toujours pratique.

public static String join(String[] strings, int startIndex, String separator) {
    StringBuffer sb = new StringBuffer();
    for (int i=startIndex; i < strings.length; i++) {
        if (i != startIndex) sb.append(separator);
        sb.append(strings[i]);
    }
    return sb.toString();
}
3
répondu SSpoke 2014-03-28 13:57:25

l'approche que j'ai adoptée a évolué depuis Java 1.0 Pour fournir la lisibilité et maintenir des options raisonnables pour rétrocompatibilité avec les versions Java plus anciennes, tout en fournissant également des signatures de méthode qui sont des remplacements pour ceux de apache commons-lang. Pour des raisons de performance, je peux voir quelques objections possibles à l'utilisation de tableaux.asList mais je préfère les méthodes d'aide qui ont des valeurs par défaut sensées sans dupliquer la méthode qui exécute le travail réel. Ce l'approche fournit des points d'entrée appropriés à une méthode fiable qui ne nécessite pas de conversions tableau/liste avant l'appel.

les variations possibles pour la compatibilité de version Java incluent le remplacement de StringBuffer (Java 1.0) par StringBuilder (Java 1.5), le remplacement de L'itérateur Java 1.5 et la suppression du caractère générique (Java 1.5) de la Collection (Java 1.2). Si vous voulez prendre rétrocompatibilité un peu plus loin, supprimer les méthodes qui utilisent Collection et déplacez la logique dans la méthode basée sur les tableaux.

public static String join(String[] values)
{
    return join(values, ',');
}

public static String join(String[] values, char delimiter)
{
    return join(Arrays.asList(values), String.valueOf(delimiter));
}

// To match Apache commons-lang: StringUtils.join(values, delimiter)
public static String join(String[] values, String delimiter)
{
    return join(Arrays.asList(values), delimiter);
}

public static String join(Collection<?> values)
{
    return join(values, ',');
}

public static String join(Collection<?> values, char delimiter)
{
    return join(values, String.valueOf(delimiter));
}

public static String join(Collection<?> values, String delimiter)
{
    if (values == null)
    {
        return new String();
    }

    StringBuffer strbuf = new StringBuffer();

    boolean first = true;

    for (Object value : values)
    {
        if (!first) { strbuf.append(delimiter); } else { first = false; }
        strbuf.append(value.toString());
    }

    return strbuf.toString();
}
2
répondu vallismortis 2015-06-15 02:04:31
public String join(String[] str, String separator){
    String retval = "";
    for (String s: str){ retval+= separator + s;}
    return retval.replaceFirst(separator, "");
}
0
répondu IvanP 2014-10-04 16:16:08