Version mise à jour utilisant Java 8 (original à la fin de l'article)
Si vous n'avez pas besoin de filtrer des éléments, vous pouvez utiliser
Depuis Java 8, nous pouvons utiliser StringJoiner
(au lieu de l'utilisation initiale de StringBulder
) et de simplifier notre code.
De même, pour éviter de recompiler " *"
dans chaque appel de matches(" *")
nous pouvons créer un modèle distinct qui conservera sa version compilée dans un champ et l'utilisera en cas de besoin.
private static final Pattern SPACES_OR_EMPTY = Pattern.compile(" *");
public static String implode(String separator, String... data) {
StringJoiner sb = new StringJoiner(separator);
for (String token : data) {
if (!SPACES_OR_EMPTY.matcher(token).matches()) {
sb.add(token);
}
}
return sb.toString();
}
Avec les flux, notre code peut ressembler à ce qui suit.
private static final Predicate<String> IS_NOT_SPACES_ONLY =
Pattern.compile("^\\s*$").asPredicate().negate();
public static String implode(String delimiter, String... data) {
return Arrays.stream(data)
.filter(IS_NOT_SPACES_ONLY)
.collect(Collectors.joining(delimiter));
}
Si nous utilisons des flux, nous pouvons filter
les éléments qui Predicate
. Dans ce cas, nous voulons que le prédicat accepte les chaînes qui ne sont pas uniquement des espaces - en d'autres termes, la chaîne doit contenir un caractère autre qu'un espace blanc.
Nous pouvons créer un tel prédicat à partir d'un motif. Le prédicat ainsi créé acceptera toutes les chaînes de caractères qui contiennent des sous-chaînes pouvant être couvertes par la regex (ainsi, si la regex recherche "\\S"
Le prédicat accepte les chaînes de caractères telles que "foo "
, " foo bar "
, "whatever"
mais n'acceptera pas " "
ni " "
).
Nous pouvons donc utiliser
Pattern.compile("\\S").asPredicate();
ou peut-être un peu plus descriptif, négation des chaînes de caractères qui ne sont que des espaces, ou vides
Pattern.compile("^\\s*$").asPredicate().negate();
Ensuite, lorsque le filtre éliminera toutes les chaînes vides ou ne contenant que des espaces, nous pourrons collect
le reste des éléments. Grâce à Collectors.joining
nous pouvons décider du délimiteur à utiliser.
Réponse originale (avant Java 8)
public static String implode(String separator, String... data) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < data.length - 1; i++) {
//data.length - 1 => to not add separator at the end
if (!data[i].matches(" *")) {//empty string are ""; " "; " "; and so on
sb.append(data[i]);
sb.append(separator);
}
}
sb.append(data[data.length - 1].trim());
return sb.toString();
}
Vous pouvez l'utiliser comme
System.out.println(implode(", ", "ab", " ", "abs"));
ou
System.out.println(implode(", ", new String[] { "ab", " ", "abs" }));
Sortie ab, abs