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

122,671

Solution 1

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.

Solution 2

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

Solution 3

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.

Solution 4

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

Solution 5

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.

Share:
122,671

Related videos on Youtube

Lars Andren
Author by

Lars Andren

Sponsored by destiny.

Updated on July 11, 2020

Comments

  • Lars Andren
    Lars Andren almost 4 years

    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 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?

  • Lars Andren
    Lars Andren about 14 years
    Thanks for your answer! I didn't put it into a separate function to highlight the fact that I am trying to reuse the 'builder'-variable. Maybe that doesn't matter?
  • Gunslinger47
    Gunslinger47 about 14 years
    It doesn't matter. Repurposing variables can actually get you into trouble down the line. Instead, just have variables go out of scope when they're no longer needed.
  • Lars Andren
    Lars Andren about 14 years
    @Gunslinger, I see, thanks! @Uri, thanks for the initial capacity tips.
  • Uri
    Uri about 14 years
    @Lars, there are cases where reuse makes sense but in others it is better to dump and start from scratch. I'm not sure what's better here. You could write a utility class that has an instance variable builder that is shared. One advantage for one-builder-per-run is that you could convert a large number of sets in parallel with multiple threads.
  • Shervin Asgari
    Shervin Asgari about 14 years
    What is the difference betweend guava-libraries and google collection library?
  • Sean Patrick Floyd
    Sean Patrick Floyd about 14 years
    the main difference is that guava knows about generics and commons/collections doesn't, but apart from that: they are two different libraries written by two different teams that solve some similar problems (and some non-similar ones) using different approaches
  • Cowan
    Cowan about 14 years
    @seanizer, Shervin was asking about guava vs google-collections, not guava vs commons :) Shervin - guava is simply the replacement for google-collections. As the project increased in scope, it stopped being limited to collections-only things so a name change was in order. google-collections should basically be considered deprecated, guava is a drop-in replacement with bug fixes + more features.
  • Kevin Bourrillion
    Kevin Bourrillion about 14 years
    brief, but inflexible. I get "" substituted for null whether I want it or not, and don't have a skip nulls option... this is why we made Joiner for Guava (see other answer).
  • Sean Patrick Floyd
    Sean Patrick Floyd about 14 years
    I usually don't have nulls in my collections, so the brief approach is fine for me, but Guava rocks! Thanks for making that happen...
  • Kevin Bourrillion
    Kevin Bourrillion about 14 years
    Since you don't expect nulls, you'd like your joiner to blow up if you did have a null -- which is what Guava's Joiner does by default. :-)
  • Lars Andren
    Lars Andren about 9 years
    Nice! Always cool to see what you can do with the JDK standard libs :)
  • smp7d
    smp7d about 7 years
    This one is null safe (when set is null) whereas the Guava approach is not
  • Sean Patrick Floyd
    Sean Patrick Floyd about 7 years
    @smp7d nor should it be. Null is not valid input. Assuming it is would be dangerous. Rejecti null values with precondition checks and you'll never have to worry about null safety again
  • Sean Patrick Floyd
    Sean Patrick Floyd over 6 years
    @java-addict301 Lots of little things, but the worst is the supposed null-safety everywhere. Read the Guava section explaining why that is a bad idea
  • java-addict301
    java-addict301 over 6 years
    @SeanPatrickFloyd Hmm, interesting looking read, thanks for the reference. I am very careful, intentional, and minimal with my use of null in general so perhaps I haven't noticed as much. Most importantly however, I always Always ALWAYS check values/parameters for null before use and throw an exception if they are, in almost all cases..
  • Lukas Novicky
    Lukas Novicky over 6 years
    clean, simple, not dependent on libraries hence not adding to app weight - love it!
  • Tedil
    Tedil almost 6 years
    ... as long as you don't have any "[" or "]"s or ","s in your set, of course ;)
  • user2808054
    user2808054 almost 6 years
    I'd already mentioned the commas but you're right about [ and ] as well. Updated the answer.
  • lewdev
    lewdev almost 4 years
    Some people are sadly without Java8+ and no easy access to libraries. Answers like this are super helpful for those people.
  • Mashukur Rahman
    Mashukur Rahman over 3 years
    be careful. if the toString is overridden it may do not work.