What's the best way to build a string of delim

2018-12-31 07:39发布

While working in a Java app, I recently needed to assemble a comma-delimited list of values to pass to another web service without knowing how many elements there would be in advance. The best I could come up with off the top of my head was something like this:

public String appendWithDelimiter( String original, String addition, String delimiter ) {
    if ( original.equals( "" ) ) {
        return addition;
    } else {
        return original + delimiter + addition;
    }
}

String parameterString = "";
if ( condition ) parameterString = appendWithDelimiter( parameterString, "elementName", "," );
if ( anotherCondition ) parameterString = appendWithDelimiter( parameterString, "anotherElementName", "," );

I realize this isn't particularly efficient, since there are strings being created all over the place, but I was going for clarity more than optimization.

In Ruby, I can do something like this instead, which feels much more elegant:

parameterArray = [];
parameterArray << "elementName" if condition;
parameterArray << "anotherElementName" if anotherCondition;
parameterString = parameterArray.join(",");

But since Java lacks a join command, I couldn't figure out anything equivalent.

So, what's the best way to do this in Java?

标签: java string
30条回答
琉璃瓶的回忆
2楼-- · 2018-12-31 08:07

You can generalize it, but there's no join in Java, as you well say.

This might work better.

public static String join(Iterable<? extends CharSequence> s, String delimiter) {
    Iterator<? extends CharSequence> iter = s.iterator();
    if (!iter.hasNext()) return "";
    StringBuilder buffer = new StringBuilder(iter.next());
    while (iter.hasNext()) buffer.append(delimiter).append(iter.next());
    return buffer.toString();
}
查看更多
梦该遗忘
3楼-- · 2018-12-31 08:08

Why don't you do in Java the same thing you are doing in ruby, that is creating the delimiter separated string only after you've added all the pieces to the array?

ArrayList<String> parms = new ArrayList<String>();
if (someCondition) parms.add("someString");
if (anotherCondition) parms.add("someOtherString");
// ...
String sep = ""; StringBuffer b = new StringBuffer();
for (String p: parms) {
    b.append(sep);
    b.append(p);
    sep = "yourDelimiter";
}

You may want to move that for loop in a separate helper method, and also use StringBuilder instead of StringBuffer...

Edit: fixed the order of appends.

查看更多
倾城一夜雪
4楼-- · 2018-12-31 08:08

Don't know if this really is any better, but at least it's using StringBuilder, which may be slightly more efficient.

Down below is a more generic approach if you can build up the list of parameters BEFORE doing any parameter delimiting.

// Answers real question
public String appendWithDelimiters(String delimiter, String original, String addition) {
    StringBuilder sb = new StringBuilder(original);
    if(sb.length()!=0) {
        sb.append(delimiter).append(addition);
    } else {
        sb.append(addition);
    }
    return sb.toString();
}


// A more generic case.
// ... means a list of indeterminate length of Strings.
public String appendWithDelimitersGeneric(String delimiter, String... strings) {
    StringBuilder sb = new StringBuilder();
    for (String string : strings) {
        if(sb.length()!=0) {
            sb.append(delimiter).append(string);
        } else {
            sb.append(string);
        }
    }

    return sb.toString();
}

public void testAppendWithDelimiters() {
    String string = appendWithDelimitersGeneric(",", "string1", "string2", "string3");
}
查看更多
高级女魔头
5楼-- · 2018-12-31 08:09

You should probably use a StringBuilder with the append method to construct your result, but otherwise this is as good of a solution as Java has to offer.

查看更多
一个人的天荒地老
6楼-- · 2018-12-31 08:10

You could write a little join-style utility method that works on java.util.Lists

public static String join(List<String> list, String delim) {

    StringBuilder sb = new StringBuilder();

    String loopDelim = "";

    for(String s : list) {

        sb.append(loopDelim);
        sb.append(s);            

        loopDelim = delim;
    }

    return sb.toString();
}

Then use it like so:

    List<String> list = new ArrayList<String>();

    if( condition )        list.add("elementName");
    if( anotherCondition ) list.add("anotherElementName");

    join(list, ",");
查看更多
余欢
7楼-- · 2018-12-31 08:12

And a minimal one (if you don't want to include Apache Commons or Gauva into project dependencies just for the sake of joining strings)

/**
 *
 * @param delim : String that should be kept in between the parts
 * @param parts : parts that needs to be joined
 * @return  a String that's formed by joining the parts
 */
private static final String join(String delim, String... parts) {
    StringBuilder builder = new StringBuilder();
    for (int i = 0; i < parts.length - 1; i++) {
        builder.append(parts[i]).append(delim);
    }
    if(parts.length > 0){
        builder.append(parts[parts.length - 1]);
    }
    return builder.toString();
}
查看更多
登录 后发表回答