1. ホーム
  2. java

[解決済み] PHP の implode(',' , array_filter( array () )) に相当する Java の処理。

2023-07-24 22:29:55

質問

私はよくPHPでこのようなコードを使用します。

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

空の文字列をクリアして、"," でつなげます。1つだけ残っている場合、不要なカンマを追加しません。末尾にカンマを付加しません。1つも残っていない場合は、空の文字列を返します。

このようにして、次のような結果を得ることができます。

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

Javaでの最適な(コードの少ない)実装は何か? 外部ライブラリを追加することなく (Android向けの設計)を教えてください。

どのように解決するのですか?

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 . この場合、述語はスペースだけでない文字列を受け入れるようにしたいのですが、言い換えれば、文字列は空白でない文字を含まなければなりません。

このような述語は、パターンから作ることができます。この方法で作られた述語は、正規表現でマッチする部分文字列を含むあらゆる文字列を受け付けます(例えば、正規表現が "\\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