Je cherche un moyen rapide et facile de faire exactement le contraire de split pour que ["a","b","c"]
devienne "a,b,c"
Pour itérer dans un tableau, vous devez soit ajouter une condition (si ce n'est pas le dernier élément, ajoutez le séparateur), soit utiliser une sous-chaîne 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?
En utilisant Java 8, vous pouvez le faire de manière très propre:
String.join(delimiter, elements);
Cela fonctionne de trois manières:
1) spécifiant directement les éléments
String joined1 = String.join(",", "a", "b", "c");
2) en utilisant des tableaux
String[] array = new String[] { "a", "b", "c" };
String joined2 = String.join(",", array);
3) en utilisant iterables
List<String> list = Arrays.asList(array);
String joined3 = String.join(",", list);
Si vous êtes sur Android, vous pouvez TextUtils.join(delimiter, tokens)
Je préfère Google Collections à Apache StringUtils pour ce problème particulier:
Joiner.on(separator).join(array)
Comparée à StringUtils, l’API Joiner a une conception fluide et est un peu plus flexible, par exemple. Les éléments null
peuvent être ignorés ou remplacés par un espace réservé. De plus, Joiner
dispose d'une fonctionnalité permettant de joindre des cartes avec un séparateur entre clé et valeur.
Apache Commons Lang possède en effet une méthode StringUtils.join
qui connectera les tableaux String
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 l'avez mentionné, la mise en œuvre effective de la méthode susmentionnée doit comporter un type de traitement conditionnel ou de sous-chaîne.
Si je devais effectuer la jonction String
et que je n'avais aucune autre raison d'utiliser Commons Lang, je roulerais probablement moi-même pour réduire le nombre de dépendances vers des bibliothèques externes.
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();
}
"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)
Avec Java 1.8, il existe un nouveau StringJoiner class - il n'est donc pas nécessaire d'utiliser Guava ou Apache Commons:
String str = new StringJoiner(",").add("a").add("b").add("c").toString();
Ou en utilisant une collection directement avec la nouvelle api de flux:
String str = Arrays.asList("a", "b", "c").stream().collect(Collectors.joining(","));
Encore plus facilement, vous pouvez simplement 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 allez vous retrouver avec ceci: concat = "[a, b, c]"
Mise à jour
Vous pouvez ensuite 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 vous retrouvez avec concat = "a, b, c"
Vous pouvez utiliser replace et replaceAll avec des expressions régulières.
String[] strings = {"a", "b", "c"};
String result = Arrays.asList(strings).toString().replaceAll("(^\\[|\\]$)", "").replace(", ", ",");
Étant donné que Arrays.asList().toString()
produit: "[a, b, c]", nous faisons un replaceAll
pour supprimer les premier et dernier crochets, puis (éventuellement) vous pouvez modifier le "," séquence pour "," (votre nouveau séparateur).
Une version stripped (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, en particulier les méthodes String "replaceFirst" et "replaceAll". Donnez-leur un essai.
Toutes ces autres réponses incluent une surcharge d'exécution ... comme l'utilisation de ArrayList.toString (). ReplaceAll (...) qui sont très inutiles.
Je vais vous donner l'algorithme optimal avec zéro overhead; cela ne semble pas aussi joli que les autres options, mais en interne, c'est ce qu'elles sont toutes en train de faire (après des piles d'autres contrôles cachés, une allocation de plusieurs tableaux et d'autres choses crud).
Comme vous savez déjà que vous traitez avec des chaînes, vous pouvez enregistrer un tas d'allocations de tableaux en effectuant tout manuellement. Cela n’est pas beau, mais si vous tracez les appels de méthode effectués par les autres implémentations, vous constaterez que le temps système d’exécution est le moins lourd 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);
}
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);
}
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();
}
L’approche que j’ai adoptée a évolué depuis Java 1.0 afin de garantir la lisibilité et de conserver des options raisonnables en matière de rétrocompatibilité avec les versions antérieures Java, tout en fournissant des signatures de méthode qui se font de manière autonome. remplacements pour ceux d’Apache commons-lang. Pour des raisons de performances, je peux voir quelques objections possibles à l’utilisation de Arrays.asList mais je préfère les méthodes auxiliaires qui ont des valeurs par défaut raisonnables sans dupliquer la méthode qui effectue le travail réel. Cette approche fournit des points d'entrée appropriés à une méthode fiable qui n'exige pas de conversions de tableaux/listes avant d'appeler.
Les variantes possibles pour la compatibilité de la version de Java incluent la substitution de StringBuffer (Java 1.0) à StringBuilder (Java 1.5), la suppression 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 souhaitez passer à la compatibilité ascendante une ou deux étapes plus loin, supprimez les méthodes qui utilisent Collection et déplacez la logique dans la méthode basée sur un tableau.
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();
}
public String join(String[] str, String separator){
String retval = "";
for (String s: str){ retval+= separator + s;}
return retval.replaceFirst(separator, "");
}