tags:

views:

9250

answers:

11

I know this is a bit of a newbie question, but are there equivalents to C#'s string operations in Java?

Specifically, I'm talking about String.Format and String.Join.

A: 

The Java String API is pretty useful...Check it out

perimosocordiae
Note that that's Java 1.3. You might be better looking at the more current 1.6 instead. http://java.sun.com/javase/6/docs/api/java/lang/String.html
izb
A: 

Absolutely

curtisk
+1  A: 

string.format

jop
+9  A: 

Yes, kinda

String.format and as for join I think you need to write your own:

 static String join(Collection<?> s, String delimiter) {
     StringBuilder builder = new StringBuilder();
     Iterator iter = s.iterator();
     while (iter.hasNext()) {
         builder.append(iter.next());
         if (!iter.hasNext()) {
           break;                  
         }
         builder.append(delimiter);
     }
     return builder.toString();
 }

The above comes from http://snippets.dzone.com/posts/show/91

Allain Lalonde
I'd suggest using StringBuilder instead of StringBuffer if you're using the appropriate version.
Jon Skeet
More precisely: StringBuffer for jdk1.4 and below, StringBuilder for jdk1.5 and after, since the latter is not synchronized, hence a little faster.
VonC
Istead of two iter.hasNext() invocations I usually append delimeter and then "return buf.substring(0, buf.length() - delimeter.length())".
Vilmantas Baranauskas
Collection should really be parameterized, as should be the Iterator. Eclipse will warn you about it, and rightly so.
Aleksandar Dimitrov
Wouldn't parametizing Collection make it difficult when joining a collection of arbitraty objects? Collection<Object> wouldn't be able to accept a Collection<String> if I remember correctly.
Allain Lalonde
You would want Collection<?>, to make your intention explicit.
Ross
Didn't know about that. Nice.
Allain Lalonde
You can streamline it a tiny bit by exiting early to avoid the delimiter: while (true) ( add_iter; if (! iter.hasNext()) break; add_delim; }
13ren
+25  A: 

The Java String object has a format method (as of 1.5), but no join method.

To get a bunch of useful String utility methods not already included you could use org.apache.commons.lang.StringUtils.

Grant Wagner
google collections: google-collections.googlecode.com has a Joiner as well.
Ron
Link above is broken as of 9/20/2010. Try http://commons.apache.org/lang/api-2.5/org/apache/commons/lang/StringUtils.html
Tony Ennis
+1  A: 

So there is a String.format but I'll have to Roll my own join.

Omar Kooheji
+1  A: 

As for join, I believe this might look a little less complicated:

public String join (Collection<String> c) {
    StringBuilder sb=new StringBuilder();
    for(String s: c)
        sb.append(s);
    return sb.toString();
}

I don't get to use Java 5 syntax as much as I'd like (Believe it or not, I've been using 1.0.x lately) so I may be a bit rusty, but I'm sure the concept is correct.

edit addition: String appends can be slowish, but if you are working on GUI code or some short-running routine, it really doesn't matter if you take .005 seconds or .006, so if you had a collection called "joinMe" that you want to append to an existing string "target" it wouldn't be horrific to just inline this:

for(String s : joinMe)
    target += s;

It's quite inefficient (and a bad habit), but not anything you will be able to perceive unless there are either thousands of strings or this is inside a huge loop or your code is really performance critical.

More importantly, it's easy to remember, short, quick and very readable. Performance isn't always the automatic winner in design choices.

Bill K
The for-loop is correct, but you should also make it a Collection<String>. If you don't, you'd have to say "for (Object o : c)", because you couldn't guarantee that everything in c was a String.
Michael Myers
Good point, I'm even more rusty with Generics. I'll edit it in.
Bill K
When concatting inline: string + string + string, the compiler actually uses StringBuilder to append the values. I wonder if in the for-loop method you have second there, whether the compiler would do the same.
Spencer K
@Spencer K: It does use a StringBuilder, but it creates a new one for each iteration (hardly the most efficient method, but then how is the compiler supposed to know?). I don't know if the JIT compiler might optimize that at runtime.
Michael Myers
The 'loop and append' style code is buggy, as it unnecessarily applies an arbitrary limit on the input range of it's arguments (based on overall memory usage and GC implementation). It should be avoided at all costs, as you never know when it will bite you.
soru
+1  A: 

If you wish to join (concatenate) several strings into one, you should use a StringBuilder. It is far better than using

for(String s : joinMe)
    target += s;

There is also a slight performance win over StringBuffer, since StringBuilder does not use synchronization.

For a general purpose utility method like this, it will (eventually) be called many times in many situations, so you should make it efficient and not allocate many transient objects. We've profiled many, many different Java apps and almost always find that string concatenation and string/char[] allocations take up a significant amount of time/memory.

Our reusable collection -> string method first calculates the size of the required result and then creates a StringBuilder with that initial size; this avoids unecessary doubling/copying of the internal char[] used when appending strings.

djb
A: 

StringUtils is a pretty useful class in the Apache Commons Lang library.

Perhaps you didn't notice that the accepted answer, posted 8 months ago, already contains that same information; http://stackoverflow.com/questions/187676/string-operations-in-java/187738#187738
Jonik
A: 

I would just use the string concatenation operator "+" to join two strings. s1 += s2;

Amir Bashir