Подтвердить что ты не робот

Java-эквивалент PHP implode (',', array_filter (array()))

Я часто использую этот кусок кода в PHP

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

Он очищает пустые строки и присоединяет их к ",". Если остается только один, он не добавляет лишнюю ненужную запятую. Он не добавляет запятую в конце. Если ни один не остается, он возвращает пустую строку.

Таким образом, я могу получить один из следующих результатов

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

Какая лучшая реализация Java (меньше кода) в Java без добавления внешних библиотек (для Android)?

4b9b3361

Ответ 1

Обновленная версия с использованием Java 8 (оригинал в конце сообщения)

Если вам не нужно фильтровать какие-либо элементы, вы можете использовать


Начиная с Java 8 мы можем использовать StringJoiner (вместо первоначально использованного StringBulder) и упростить наш код.
Кроме того, чтобы не перекомпилировать регулярное выражение " *" в каждом вызове matches(" *"), мы можем создать отдельный шаблон, который будет содержать свою скомпилированную версию в некотором поле и использовать ее при необходимости.

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

С потоками, которые наш код может выглядеть.

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

Если мы используем потоки, мы можем filter элементы, которые Predicate. В этом случае мы хотим, чтобы предикат принимал строки, которые являются не только пробелами - другими словами, строка должна содержать не-пробельный символ.

Мы можем создать такой Предикат из шаблона. Созданный таким образом предикат примет любые строки, которые будут содержать подстроку, которая может быть сопоставлена ​​с помощью регулярных выражений (так что если regex будет искать "\\S", предикат будет принимать строки типа "foo ", " foo bar ", "whatever", но не примет " " и " ").

Таким образом, мы можем использовать

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

или, возможно, немного более описательным, отрицанием строк, которые являются только пробелами, или пустым

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

Далее, когда фильтр удалит все пустое или содержащее только пробелы Строки, мы можем collect остальные элементы. Благодаря Collectors.joining мы можем решить, какой разделитель использовать.


Оригинальный ответ (до 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();
}

Вы можете использовать его как

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

или

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

Выход ab, abs

Ответ 2

Почему так серьезно? Попробуйте StringUtils.join(new String[] {"Hello", "World", "!"}, ", ")!

Ответ 3

Вам нужно добавить свои строки в ArrayList, удалить пустые и соответствующим образом отформатировать:

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

Кроме того, если у вас есть String[], массив строк, вы можете легко добавить их в ArrayList:

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

Ответ 4

Вот конкретный ответ на Android, который может быть полезен для некоторых

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

//Result => Red,Green,Blue

Обязательно импортируйте класс TextUtils

import android.text.TextUtils;

Ответ 5

Простой 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;
}

Вы можете создать для него перегрузки.

Вышеупомянутый эквивалент php implode.
Вот что вы хотите:

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

Ответ 6

Использование Streams (для java 8 и более поздних версий) было бы альтернативным возможным решением для этого. Вы должны импортировать

java.util.stream.Collectors;

использовать процесс соединения

Вы можете использовать:

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

для достижения желаемого результата.

Ответ 7

Здесь моя реализация implode:

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

Ответ 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();
    }

Ответ 9

используйте эту простую функцию:

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

использовать:

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