开发者

Fastest way to put contents of Set<String> to a single String with words separated by a whitespace?

I have a few Set<String>s and want to transform each of these into a single String where each element of the original Set is separated by a whitespace " ". A naive first approach开发者_JAVA技巧 is doing it like this

Set<String> set_1;
Set<String> set_2;

StringBuilder builder = new StringBuilder();
for (String str : set_1) {
  builder.append(str).append(" ");
}

this.string_1 = builder.toString();

builder = new StringBuilder();
for (String str : set_2) {
  builder.append(str).append(" ");
}

this.string_2 = builder.toString();

Can anyone think of a faster, prettier or more efficient way to do this?


With commons/lang you can do this using StringUtils.join:

String str_1 = StringUtils.join(set_1, " ");

You can't really beat that for brevity.

Update:

Re-reading this answer, I would prefer the other answer regarding Guava's Joiner now. In fact, these days I don't go near apache commons.

Another Update:

Java 8 introduced the method String.join()

String joined = String.join(",", set);

While this isn't as flexible as the Guava version, it's handy when you don't have the Guava library on your classpath.


If you are using Java 8, you can use the native

String.join(CharSequence delimiter, Iterable<? extends CharSequence> elements)

method:

Returns a new String composed of copies of the CharSequence elements joined together with a copy of the specified delimiter. For example:

 Set<String> strings = new LinkedHashSet<>();
 strings.add("Java"); strings.add("is");
 strings.add("very"); strings.add("cool");
 String message = String.join("-", strings);
 //message returned is: "Java-is-very-cool"

Set implements Iterable, so simply use:

String.join(" ", set_1);


As a counterpoint to Seanizer's commons-lang answer, if you're using Google's Guava Libraries (which I'd consider the 'successor' to commons-lang, in many ways), you'd use Joiner:

Joiner.on(" ").join(set_1);

with the advantage of a few helper methods to do things like:

Joiner.on(" ").skipNulls().join(set_1);
// If 2nd item was null, would produce "1, 3"

or

Joiner.on(" ").useForNull("<unknown>").join(set_1);
// If 2nd item was null, would produce "1, <unknown>, 3"

It also has support for appending direct to StringBuilders and Writers, and other such niceties.


Maybe a shorter solution:

public String test78 (Set<String> set) {
    return set
        .stream()
        .collect(Collectors.joining(" "));
}

or

public String test77 (Set<String> set) {
    return set
        .stream()
        .reduce("", (a,b)->(a + " " + b));
}

but native, definitely faster

public String test76 (Set<String> set) {
    return String.join(" ", set);
}


I don't have the StringUtil library available (I have no choice over that) so using standard Java I came up with this ..

If you're confident that your set data won't include any commas or square brackets, you could use:

mySet.toString().replaceAll("\\[|\\]","").replaceAll(","," ");

A set of "a", "b", "c" converts via .toString() to string "[a,b,c]".

Then replace the extra punctuation as necesary.

Filth.


I use this method:

public static String join(Set<String> set, String sep) {
    String result = null;
    if(set != null) {
        StringBuilder sb = new StringBuilder();
        Iterator<String> it = set.iterator();
        if(it.hasNext()) {
            sb.append(it.next());
        }
        while(it.hasNext()) {
            sb.append(sep).append(it.next());
        }
        result = sb.toString();
    }
    return result;
}


I'm confused about the code replication, why not factor it into a function that takes one set and returns one string?

Other than that, I'm not sure that there is much that you can do, except maybe giving the stringbuilder a hint about the expected capacity (if you can calculate it based on set size and reasonable expectation of string length).

There are library functions for this as well, but I doubt they're significantly more efficient.


This can be done by creating a stream out of the set and then combine the elements using a reduce operation as shown below (for more details about Java 8 streams check here):

Optional<String> joinedString = set1.stream().reduce(new 
BinaryOperator<String>() {

     @Override
     public String apply(String t, String u) {

       return t + " " + u;
    }
});
return joinedString.orElse("");
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜