Java-equivalent van PHP’s implode(‘,’ , array_filter( array () ))

Ik gebruik dit stukje code vaak in PHP

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

Het wist lege strings en voegt ze samen met een “,”. Als er maar één overblijft, voegt het geen extra onnodige komma toe. Het voegt geen komma toe aan het einde. Als er geen overblijft, wordt een lege tekenreeks geretourneerd.

Zo kan ik een van de volgende resultaten krijgen

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

Wat is de beste Java-implementatie (minder code) in Java zonder externe bibliotheken toe te voegen(ontwerpen voor Android)?


Antwoord 1, autoriteit 100%

Bijgewerkte versie met Java 8 (origineel aan het einde van de post)

Als u geen elementen hoeft te filteren, kunt u die gebruiken


Sinds Java 8 kunnen we StringJoinergebruiken (in plaats van de oorspronkelijk gebruikte StringBulder) en onze code vereenvoudigen.
Om te voorkomen dat de regex van " *"opnieuw wordt gecompileerd in elke aanroep van matches(" *"), kunnen we een afzonderlijk patroon maken dat de gecompileerde versie in een veld zal bewaren en het gebruiken wanneer nodig.

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();
}   

Met streams kan onze code eruitzien.

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));
}

Als we streams gebruiken, kunnen we filterelementen die Predicate. In dit geval willen we dat het predikaat tekenreeksen accepteert die niet alleen spaties zijn – met andere woorden: tekenreeks mag geen witruimteteken bevatten.

We kunnen zo’n predikaat maken op basis van Pattern. Predikaat dat op deze manier is gemaakt, accepteert alle tekenreeksen die subtekenreeksen bevatten die overeenkomen met regex (dus als regex zoekt naar "\\S", accepteert het predikaat tekenreeksen zoals "foo ", " foo bar ", "whatever", maar accepteert geen " "noch " ") .

Zodat we kunnen gebruiken

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

of mogelijk iets meer beschrijvend, ontkenning van strings die alleen spaties zijn, of leeg

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

De volgende keer dat filter alle lege of spaties verwijdert Strings die we kunnen collectde rest van de elementen. Dankzij Collectors.joiningkunnen we beslissen welk scheidingsteken we gebruiken.


Oorspronkelijk antwoord (vóór 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();
}

Je kunt het gebruiken als

System.out.println(implode(", ", "ab", " ", "abs"));

of

System.out.println(implode(", ", new String[] { "ab", " ", "abs" }));

Uitvoer ab, abs


Antwoord 2, autoriteit 83%

Waarom zo serieus?
Probeer StringUtils.join(new String[] {"Hello", "World", "!"}, ", ")!


Antwoord 3, autoriteit 21%

Hier is een Android-specifiek antwoord dat voor sommigen nuttig kan zijn:

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

Zorg ervoor dat u de TextUtils-klasse importeert:

import android.text.TextUtils;

Antwoord 4, autoriteit 18%

Je moet je strings toevoegen aan een ArrayList, lege strings verwijderen en dienovereenkomstig formatteren:

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();
}

Bovendien, als u String[]had, een array van strings, kunt u deze eenvoudig toevoegen aan een ArrayList:

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

Antwoord 5, autoriteit 2%

Een simpele 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;
}

Je kunt er overbelasting voor creëren..

Het bovenstaande equivalent van php implode.
Dit is wat je wilt:

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;
}

Antwoord 6, autoriteit 2%

Het gebruik van Streams (voor Java 8en hoger) zou een alternatieve mogelijkheid zijn oplossing hiervoor.

U moet importeren

java.util.stream.Collectors;

om het deelnameproces te gebruiken

U mag het volgende gebruiken:

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

om het gewenste resultaat te bereiken.


Antwoord 7

Hier is mijn implodatie-implementatie:

/**
 * 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();
}

Antwoord 8

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();
    }

Antwoord 9

Gebruik deze eenvoudige functie:

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;
}

Gebruik:

data_arr = {"d1", "d2", "d3"};
your_imploded_text = my_implode(",", data_arr);
// Output: your_imploded_text = "d1,d2,d3"

Other episodes