Java 等效于 PHP 的内爆(’,’,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而不必添加外部库(为 Android 设计)中最好的 Java 实现(更少的代码) ?

88051 次浏览

简单的内爆

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 内爆。
这是你想要的:

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

您必须将字符串添加到数组列表中,删除空字符串,并相应地对其进行格式化:

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[],你可以很容易地将它们添加到数组列表:

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

使用 Java8的更新版本(原始版本在后)

如果您不需要过滤任何可以使用的元素

  • Join (CharSequence 分隔符,字符序列..。元素)

    • String.join(" > ", new String[]{"foo", "bar"});
    • String.join(" > ", "foo", "bar");

  • 或者 < a href = “ http://docs.oracle.com/javase/8/docs/api/java/lang/String.html # join-java.lang.CharSequence-java.lang.Iterable-”rel = “ noReferrer”> String.join (CharSequendelimiter,可迭代的 < ? 扩展 CharSequence > 元素)

    • String.join(" > ", Arrays.asList("foo", "bar"));

从 Java8开始,我们可以使用 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,我们可以决定使用哪个分隔符。


原答案(Java8之前)

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

为什么这么严肃? 试试 StringUtils.join(new String[] {"Hello", "World", "!"}, ", ")

下面是我的内爆实现:

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

使用这个简单的函数:

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"

下面是一个 Android 特有的答案,可能对一些人有帮助:

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


// Result => Red,Green,Blue

确保导入 TextUtils 类:

import android.text.TextUtils;
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();
}

使用 Streams (对于 爪哇8和更高版本)可能是解决这个问题的另一种可能的解决方案。

你必须输入

java.util.stream.Collectors;

使用连接进程

你可使用:

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

达到预期的结果。