web-dev-qa-db-fra.com

Equivalent Java de l'implode PHP (',', array_filter (array ()))

J'utilise souvent ce code en PHP

$ordine['address'] = implode(', ', array_filter(array($cliente['cap'], $cliente['citta'] ,$cliente['provincia'])));

Il efface les chaînes vides et les joint avec un ",". S'il n'en reste qu'un, cela n'ajoute pas une virgule inutile. Il n'ajoute pas de virgule à la fin. S'il n'en reste aucun, il retourne une chaîne vide.

Ainsi, je peux obtenir l'un des résultats suivants

""
"Street abc 14"
"Street abc 14, 00168"
"Street abc 14, 00168, Rome"

Quelle est la meilleure implémentation Java (moins de code) en Java sans avoir à ajouter de bibliothèques externes (conception pour Android)? 

63
max4ever

Version mise à jour avec Java 8 (original à la fin du message)

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'origine StringBulder) et simplifier notre code.
Pour éviter de recompiler " *" regex dans chaque appel de matches(" *"), nous pouvons créer un motif séparé qui conservera sa version compilée dans un champ et l’utilisera si nécessaire.

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.

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 éléments qui Predicate. Dans ce cas, nous voulons que le prédicat accepte les chaînes qui ne sont pas que des espaces - en d'autres termes, les chaînes doivent contenir des caractères non blancs.

Nous pouvons créer un tel prédicat à partir de Pattern. Le prédicat créé de cette manière acceptera toutes les chaînes qui contiendront une sous-chaîne qui pourrait être mise en correspondance par regex (ainsi, si regex cherchera "\\S", le prédicat acceptera des chaînes comme "foo ", " foo bar ", "whatever", mais n'acceptera pas " " ni " ").

Donc on peut utiliser

Pattern.compile("\\S").asPredicate();

ou éventuellement un peu plus descriptif, la négation de chaînes qui ne sont que des espaces, ou vides

Pattern.compile("^\\s*$").asPredicate().negate();

Ensuite, lorsque le filtre supprimera tous les espaces vides ou ne contenant que des espaces, nous pouvons collect reste d'éléments. Grâce à Collectors.joining, nous pouvons choisir le 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

80
Pshemo

Pourquoi si grave? Essayez StringUtils.join(new String[] {"Hello", "World", "!"}, ", ")!

76
Bogdan Burim

Vous devez ajouter vos chaînes à une liste de tableaux, supprimer celles vides et le formater en conséquence:

public static String createAddressString( String street, String Zip_code, String country) {
    List<String> list = new ArrayList<String>();
    list.add( street);
    list.add( Zip_code);
    list.add( country);

    // Remove all empty values
    list.removeAll(Arrays.asList("", null));

    // If this list is empty, it only contained blank values
    if( list.isEmpty()) {
        return "";
    }

    // Format the ArrayList as a string, similar to implode
    StringBuilder builder = new StringBuilder();
    builder.append( list.remove(0));

    for( String s : list) {
        builder.append( ", ");
        builder.append( s);
    }

    return builder.toString();
}

De plus, si vous avez String[], un tableau de chaînes, vous pouvez facilement les ajouter à un ArrayList:

String[] s;
List<String> list = new ArrayList<String>( Arrays.asList( s));
17
nickb

Voici une réponse spécifique à Android qui pourrait être utile à certains

String combined = TextUtils.join(",", new String[]{"Red", "Green", "Blue"});

//Result => Red,Green,Blue

Assurez-vous d'importer la classe TextUtils

import Android.text.TextUtils;
12
dloomb

L’utilisation de Streams (pour Java 8 et versions ultérieures) serait une autre solution possible pour cela. 

Java.util.stream.Collectors;

utiliser le processus de jointure

Vous pouvez utiliser:

Arrays.asList("foo","bar").stream().collect(Collectors.joining(","));

pour obtenir le résultat souhaité.

2
Aman J

Un simple implode 

public static String implode(String glue, String[] strArray)
{
    String ret = "";
    for(int i=0;i<strArray.length;i++)
    {
        ret += (i == strArray.length - 1) ? strArray[i] : strArray[i] + glue;
    }
    return ret;
}

Vous pouvez créer des surcharges pour cela ..

L'équivalent ci-dessus de php implose.
Voici ce que vous voulez: 

import Java.lang.*
public static String customImplode(String glue, String[] strArray)
{
    String ret = "";
    for(int i=0;i<strArray.length;i++)
    {
        if (strArray[i].trim() != "")
            ret += (i == strArray.length - 1) ? strArray[i] : strArray[i] + glue;
    }
    return ret;
}
2
Soroush Khosravi
public static String implode(List<String> items, String separator) {

        if (items == null || items.isEmpty()) {
            return null;
        }
        String delimiter = "";
        StringBuilder builder = new StringBuilder();
        for (String item : items) {
            builder.append(delimiter).append(item);
            delimiter = separator;
        }
        return builder.toString();
    }
1
Ahmad

Voici ma mise en œuvre implodée:

/**
 * Implodes the specified items, gluing them using the specified glue replacing nulls with the specified
 * null placeholder.
 * @param glue              The text to use between the specified items.
 * @param nullPlaceholder   The placeholder to use for items that are <code>null</code> value.
 * @param items             The items to implode.
 * @return  A <code>String</code> containing the items in their order, separated by the specified glue.
 */
public static final String implode(String glue, String nullPlaceholder, String ... items) {
    StringBuilder sb = new StringBuilder();
    for (String item : items) {
        if (item != null) {
            sb.append(item);
        } else {
            sb.append(nullPlaceholder);
        }
        sb.append(glue);
    }
    return sb.delete(sb.length() - glue.length(), sb.length()).toString();
}
1
Ben Barkay

utilisez cette fonction simple:

private String my_implode(String spacer,String[] in_array){

    String res = "";

    for(int i = 0 ; i < in_array.length ; i++){

        if( !res.equals("") ){
            res += spacer;
        }
        res += in_array[i];
    }

    return res;
}

utilisation : 

data_arr = {"d1","d2","d3"};
your_imploded_text = my_implode(",", data_arr);
//output : your_imploded_text = "d1,d2,d3"
0
Ferhad Konar