Java Forum / General / October 2007
Formatting a string in Java
Jerry Manner - 28 Sep 2007 10:28 GMT Hi
I am a newby in Java and am trying to format a string into a fixed number of positions( in this case 5). So if I have a "5" in should be "00005", and "23" should be "00023".
I hav tried looking at the classes 'import java.text.NumberFormat' and 'import java.text.Format', but I didn't get far.
Can anyone help me how I can do this in java?
Any help will be appreciated.
Regards
Jean-Baptiste Nizet - 28 Sep 2007 11:27 GMT > Hi > [quoted text clipped - 6 lines] > > Can anyone help me how I can do this in java? If the string you want to format always represents a positive integer, you might use a DecimalFormat:
NumberFormat format = new DecimalFormat("00000"); System.out.println(format.format(Integer.parseInt("23"))); System.out.println(format.format(Integer.parseInt("5")));
Else, the following code snippet works as well. Pretty basic programming:
private static String format(String s) { int length = s.length(); if (length >= 5) { return s; } else { StringBuffer buffer = new StringBuffer(5); for (int i = length; i < 5; i++) { buffer.append('0'); } buffer.append(s); return buffer.toString(); } }
JB.
Lionel van den Berg - 28 Sep 2007 12:00 GMT >> Hi >> [quoted text clipped - 31 lines] > } > } That seems longer than necessary, why not:
private static String format(String s) { String formattedString = s;
while(formattedString.length() < 5) { formattedString = "0" + formattedString; } return formattedString; }
You could provide length as a parameter too.
Lionel.
P.S. in your example I think you wanted to prepend to buffer?
Lionel.
Jürgen Gerstacker - 28 Sep 2007 12:06 GMT Why not
String.format("%05d", 5); String.format("%05d", 23);
?
Juergen
Jean-Baptiste Nizet - 28 Sep 2007 12:52 GMT On 28 sep, 13:06, J?rgen Gerstacker <ffm1...@gmx.de> wrote:
> Why not > > String.format("%05d", 5); > String.format("%05d", 23); Because the OP wants to format Strings, and not integers. But thanks to remind me that the String.format method exists. Since I learnt Java a long long time ago and this method didn't exist at the time, I've not taken the habit to use it.
JB.
Jean-Baptiste Nizet - 28 Sep 2007 12:50 GMT > That seems longer than necessary, why not: > [quoted text clipped - 7 lines] > > } Because concatenating strings in a loop is very bad practice. It's one of the main reasons of the existence of the StringBuffer class (I should have used a StringBuilder, in fact, which is even more performant). Indeed, your code after compilation is equivalent, AFAIR, to the following:
while (formattedString.length() < 5) { StringBuffer tmp = new StringBuffer(); tmp.append("0"); tmp.append(formattedString); formattedString = tmp.toString(); }
You see that lots of StringBuffer and String instances are created, which makes the performance of such code terrible. Moreover, my code also avoids calling the String length method at each iteration.
JB.
Lew - 28 Sep 2007 12:59 GMT > while (formattedString.length() < 5) { > StringBuffer tmp = new StringBuffer(); > tmp.append("0"); > tmp.append(formattedString); > formattedString = tmp.toString(); > } Sigh.
> You see that lots of StringBuffer and String instances are created, > which makes the performance of such code terrible. Nothing wrong with creating lots of StringBuffers except that you should've used StringBuilder.
Here's a better loop:
int len = formatted.length(); // why put "String" in the name of a String? StringBuilder sb = new StringBuilder( "" ); while ( len++ < 5 ) { sb.append( '0' ); } formatted = sb.append( formatted ).toString();
You can wrap the whole loop and reassignment in an if ( len < 5 ) to short-circuit unnecessary reassignment of "formatted".
 Signature Lew
Lew - 28 Sep 2007 13:00 GMT > StringBuilder sb = new StringBuilder( "" ); equivalent to StringBuilder sb = new StringBuilder();
but I wanted to make the intent here crystal clear.
 Signature Lew
Jean-Baptiste Nizet - 28 Sep 2007 13:24 GMT > > while (formattedString.length() < 5) { > > StringBuffer tmp = new StringBuffer(); [quoted text clipped - 25 lines] > if ( len < 5 ) > to short-circuit unnecessary reassignment of "formatted". Sigh.
You should re-read my first post in this thread, then the reply from Lionel van den Berg, and my reply to his reply, to which you have just answered with a "Sigh". The text, in English, before and after the code snippets, is part of the post, and you should read it as well. The code snippet was precisely there to explain to Lionel why he must not concatenate Strings inside loops, since doing it results in the same bytecode as the ugly loop above, with lots of StringBuffer and String creations.
JB.
Lew - 29 Sep 2007 03:54 GMT >>> while (formattedString.length() < 5) { >>> StringBuffer tmp = new StringBuffer(); >>> tmp.append("0"); >>> tmp.append(formattedString); >>> formattedString = tmp.toString(); Note the String creation inside the loop, which we should seek to avoid, no?
>>> } Lew wrote:
>> Sigh. >> [quoted text clipped - 12 lines] >> if ( len < 5 ) >> to short-circuit unnecessary reassignment of "formatted".
> Sigh. > [quoted text clipped - 3 lines] > The text, in English, before and after the code snippets, is part of > the post, and you should read it as well. Can we say, "supercilious"?
> The code snippet was precisely there to explain to Lionel why he must not concatenate > Strings inside loops, since doing it results in the same bytecode as > the ugly loop above, with lots of StringBuffer and String creations. If you're referring to the loop I posted, it had no StringBuffer nor String creation inside the loop. It didn't even have any StringBuilder creation inside the loop.
Actually, I did read it. My response quoted the relevant part of that discussion. And your code re-instantiated Strings inside the loop, which is quite nearly as bad.
My sigh was for the extra String being created inside the loop:
>>> formattedString = tmp.toString(); The StringBuilder approach I posted does not create lots of Strings. It creates exactly one. Yours creates one in each loop iteration.
Thus the bytecode is different.
 Signature Lew
Lew - 29 Sep 2007 03:59 GMT > You should re-read my first post in this thread, then the reply from > Lionel van den Berg, and my reply to his reply, to which you have just [quoted text clipped - 4 lines] > Strings inside loops, since doing it results in the same bytecode as > the ugly loop above, with lots of StringBuffer and String creations. Can we say, "supercilious"?
Yes, you are right. I reviewed the text and corrected my interpretation.
 Signature Lew
Lew - 29 Sep 2007 04:04 GMT > You should re-read my first post in this thread, then the reply from > Lionel van den Berg, and my reply to his reply, to which you have just [quoted text clipped - 4 lines] > Strings inside loops, since doing it results in the same bytecode as > the ugly loop above, with lots of StringBuffer and String creations. I'll get this right yet.
Yes, you are correct. I have reviewed the text and corrected my interpretation.
I was trying to say the exact same thing you were, but got entangled in it and confused. I think I have the sequence right now, though.
 Signature Lew
Chris ( Val ) - 09 Oct 2007 12:08 GMT > > while (formattedString.length() < 5) { > > StringBuffer tmp = new StringBuffer(); [quoted text clipped - 19 lines] > { > sb.append( '0' );} [snip]
It might pay to redesign the above in a way where the field width of the can be altered dynamically via an argument passed to a function or some such:
for( int index = 0; index < ( fieldWidth - src.length() ); ++index ) { sb.append( c ); }
A C++ std::string has an overloaded constructor that allows you to pre allocate it with a specific character as follows:
std::string s( '0', length );
I looked at Java' String class and StringBuilder and unfortunately couldn't find an equivalent.
If Java has no operator overloading, how could I create my own class to return a value?
E.g:
String s = MyString( '0', length );
Is that possible or do I have to build a method for it and then call that?
String s = MyString( '0', length ).get(); Or... String s = new MyString( '0', length ).get();
Thanks,
Chris
Lew - 09 Oct 2007 14:35 GMT > A C++ std::string has an overloaded constructor > that allows you to pre allocate it with a specific [quoted text clipped - 4 lines] > I looked at Java' String class and StringBuilder > and unfortunately couldn't find an equivalent. Then you missed
> String(char[] value) Not as direct but just as effective if combined with <http://java.sun.com/javase/6/docs/api/java/util/Arrays.html#fill(char[],%20char)>
You can do the same thing with StringBuilder's
> StringBuilder append(char[] str) char[] str = new char[LEN];
// already filled with zeros, so StringBuilder sb = new StringBuilder( str.length ).append( str );
> If Java has no operator overloading, how could I > create my own class to return a value? > > E.g: [sic] > > String s = MyString( '0', length ); I don't see any operator overloading here.
> Is that possible or do I have to build a method > for it and then call that? You have to build a method.
> String s = MyString( '0', length ).get(); > Or... > String s = new MyString( '0', length ).get(); You will not be able to use this idiom. You can make a MyString that implements CharSequence and has a "filler" constructor, then use that in the constructor <http://java.sun.com/javase/6/docs/api/java/lang/StringBuilder.html#StringBuilder (java.lang.CharSequence)> and then in turn use the constructor <http://java.sun.com/javase/6/docs/api/java/lang/String.html#String(java.lang.Str ingBuilder)>
 Signature Lew
Chris ( Val ) - 09 Oct 2007 16:09 GMT > > A C++ std::stringhas an overloaded constructor > > that allows you to pre allocate it with a specific [quoted text clipped - 8 lines] > > >String(char[] value) No, I didn't miss it, its just not the same thing.
The C++ std::string has many constructor overloads, and can even create temporary strings as shown in my example (notice there is no identifier declared).
Additionally, it is not limited to default padding, and I can put any fill character in there I like:
std::strings( 'X', length );
> Not as direct but just as effective if combined with > <http://java.sun.com/javase/6/docs/api/java/util/Arrays.html#fill(char[],%20char)> [quoted text clipped - 7 lines] > // already filled with zeros, so > StringBuilder sb = new StringBuilder( str.length ).append( str ); Yes, I knew you could do that, but it's not quite the same thing, and does not offer the same advantage in being able to use different characters for padding.
> > IfJavahas no operator overloading, how could I > > create my own class to return a value? [quoted text clipped - 4 lines] > > I don't see any operator overloading here. Technically, I guess it is a conversion operator.
In either case, the objective is to return an appropriate data type back to the caller via assignment, where the data returned would in this contect be the modified string that was created via its constructor.
> > Is that possible or do I have to build a method > > for it and then call that? > > You have to build a method. Thats what I was afraid of :-)
> >Strings = MyString( '0', length ).get(); > > Or... [quoted text clipped - 6 lines] > and then in turn use the constructor > <http://java.sun.com/javase/6/docs/api/java/lang/String.html#String(ja...)> Ok, I will take a look.
Thanks again,
Chris
Lew - 09 Oct 2007 23:14 GMT Lew wrote:
>>> String(char[] value)
> No, I didn't miss it, its just not the same thing. > [quoted text clipped - 6 lines] > > std::strings( 'X', length ); As I said, and you quoted,
>> Not as direct but just as effective if combined with >> <http://java.sun.com/javase/6/docs/api/java/util/Arrays.html#fill(char[],%20char)> , which allows you to fill with any character you like.
 Signature Lew
Chris ( Val ) - 11 Oct 2007 13:30 GMT > Lew wrote: > >>>String(char[] value) [quoted text clipped - 14 lines] > >> Not as direct but just as effective if combined with > >> <http://java.sun.com/javase/6/docs/api/java/util/Arrays.html#fill(char[],%20char)> Well yes, but my point was that it requires two operations instead of one (before I fit it into a String or StringBuilder object), and it is impossible to work with a temporary in the same way you can with the C++ std::string.
E.g:
char[] foo = new char[ L1 - L2 ]; Arrays.fill( foo, '0' );
String x = new String( foo ) + arg;
> , which allows you to fill with any character you like. Yes, it does, but in a quirky kind of way, I think :-)
Also, I'm not sure what you were thinking here, but I don't think the following is quite correct:
== <QUOTE FROM EARLIER POST> ==
> char[] str = new char[LEN];
> // already filled with zeros, so > StringBuilder sb = new StringBuilder( str.length ).append( str ); == </QUOTE FROM EARLIER POST> ==
It looks like you are implying that by providing 'str.length' to the StringBuilder' constructor, that it will be initialised with 'zeros' == to 'str.length' before appending 'str'.
Passing an integer to the StringBuilder constructor only increases it's capacity (which is 16 by default anyway), and does not add any elements to it.
Cheers,
Chris
Lew - 11 Oct 2007 17:22 GMT > Also, I'm not sure what you were thinking here, but I > don't think the following is quite correct: [quoted text clipped - 9 lines] > to the StringBuilder' constructor, that it will be initialised > with 'zeros' == to 'str.length' before appending 'str'. Not at all. No implication at all, much less that one.
> Passing an integer to the StringBuilder constructor only > increases it's [sic: should be "its"] capacity (which is 16 by default anyway), I was generalizing: Notice I used "LEN", not "16". This way, if you have a string longer than 16 characters, you'll get the StringBuilder of the correct size, and thus save re-allocation.
> and does not add any elements to it. So?
Look again:
> StringBuilder sb = new StringBuilder( str.length ).append( str );
 Signature Lew
Chris ( Val ) - 12 Oct 2007 14:06 GMT > > Also, I'm not sure what you were thinking here, but I > > don't think the following is quite correct: [quoted text clipped - 11 lines] > > Not at all. No implication at all, much less that one. Ok.
> > Passing an integer to the StringBuilder constructor only > > increases it's [sic: should be "its"] capacity (which is 16 by default anyway), Yes, you are correct - I got the context confused. It can happen when you're not concentrating, especially when using google groups.
I will try to be a little more alert to these kind of mistakes in the future, but don't let me catch you making any, because I will let you know about it :-)
> I was generalizing: Notice I used "LEN", not "16". This way, if you have astringlonger than 16 characters, you'll get the StringBuilder of the correct > size, and thus savere-allocation. Yes, I did noticed it.
However, in the context of the OP's question, it is unlikely that a width greater than 16 was required, given that both examples he provided demonstrated a width of 5.
> > and does not add any elements to it. > [quoted text clipped - 3 lines] > > > StringBuilder sb = new StringBuilder( str.length ).append( str ); I have looked, but I think you missunderstood what I stated.
To clarify, the following:
"new StringBuilder( str.length )"
...in itself does not add any elements to sb, and only increases the capacity - That is all that I was referring to.
In any case, since you have what you want in a char[] at this point in time, you could have just stuck it into a "new String( str )", and skipped the use of the StringBuilder class altogether.
-- Chris
Lew - 12 Oct 2007 14:37 GMT > I will try to be a little more alert to these kind of > mistakes in the future, but don't let me catch you > making any, because I will let you know about it :-) I welcome your corrections. One should never presume one is infallible.
> However, in the context of the OP's question, it is > unlikely that a width greater than 16 was required, > given that both examples he provided demonstrated > a width of 5. Ok.
>>> StringBuilder sb = new StringBuilder( str.length ).append( str );
> I have looked, but I think you missunderstood what I stated. > [quoted text clipped - 4 lines] > ....in itself does not add any elements to sb, and only increases > the capacity - That is all that I was referring to. Right, which is why there's an append() there. I never claimed that the constructor set things to zeros. Why did the point needed stating?
> In any case, since you have what you want in a char[] > at this point in time, you could have just stuck it > into a "new String( str )", and skipped the use of > the StringBuilder class altogether. Excellent point. Thank you.
 Signature Lew
Chris ( Val ) - 12 Oct 2007 15:04 GMT [snip]
> > To clarify, the following: > [quoted text clipped - 5 lines] > Right, which is why there's an append() there. I never claimed that the > constructor set things to zeros. Why did the point needed stating? [snip]
Like I stated earlier, I was not sure what you were thinking, because it wasn't all that clear:
<QUOTE> char[] str = new char[LEN];
// already filled with zeros, so StringBuilder sb = new StringBuilder( str.length ).append( str ); </QUOTE>
Adding comments to ones code is a good thing, but your comment appeared to be referring to the StringBuilder code rather than 'str', which caused me some confusion.
-- Chris
Lionel van den Berg - 28 Sep 2007 23:23 GMT >> That seems longer than necessary, why not: >> [quoted text clipped - 24 lines] > You see that lots of StringBuffer and String instances are created, > which makes the performance of such code terrible. I wise man told me, write neat code first and don't worry about performance. If performance becomes a problem then go back an worry about it.
I will stick to my neat version, but thanks for your explanation.
Actually, it wasn't wise man, it is what is taught in most Universities these days.
Lionel.
Lew - 28 Sep 2007 12:50 GMT > private static String format(String s) { > String formattedString = s; > > while(formattedString.length() < 5) { > formattedString = "0" + formattedString; This type of thing is often a frequently-traversed code path, making it a prime candidate to use StringBuilder to avoid all those messy intermediate String objects.
> } > return formattedString; > }
 Signature Lew
Jerry Manner - 28 Sep 2007 12:03 GMT > > Hi > [quoted text clipped - 33 lines] > > JB. Hi
Thank you very much. Your tip helped me alot. Up to the next challenge for me :-)
Kind Regards
Roedy Green - 29 Sep 2007 05:11 GMT On Fri, 28 Sep 2007 10:27:59 -0000, Jean-Baptiste Nizet <jnizet@gmail.com> wrote, quoted or indirectly quoted someone who said
>System.out.println(format.format(Integer.parseInt("23"))); >System.out.println(format.format(Integer.parseInt("5"))); you could write that more simply as
>System.out.println(format.format(23)); >System.out.println(format.format(5));  Signature Roedy Green Canadian Mind Products The Java Glossary http://mindprod.com
Roedy Green - 29 Sep 2007 05:13 GMT On Fri, 28 Sep 2007 02:28:00 -0700, Jerry Manner <goodminded@hotmail.com> wrote, quoted or indirectly quoted someone who said :
>I am a newby in Java and am trying to format a string into a fixed >number of positions( in this case 5). >So if I have a "5" in should be "00005", and "23" should be "00023". see StringTools.lz.
http://mindprod.com/products1.html#COMMON11.
It uses a technique similar to the append '0' in a loop, but without the overhead.
 Signature Roedy Green Canadian Mind Products The Java Glossary http://mindprod.com
Arne Vajhøj - 09 Oct 2007 03:45 GMT > I am a newby in Java and am trying to format a string into a fixed > number of positions( in this case 5). [quoted text clipped - 4 lines] > > Can anyone help me how I can do this in java? You have seen loop with String, loop with StringBuffer, loop with StringBuilder.
May I suggest:
s = "00000".substring(s.length()) + s;
or if it may be longer than 5:
if(s.length() < 5) s = "00000".substring(s.length()) + s;
Arne
Roedy Green - 10 Oct 2007 00:13 GMT >s = "00000".substring(s.length()) + s; That is a method in the StringTools class. See http://mindprod.com/products1.html#COMMON11
 Signature Roedy Green Canadian Mind Products The Java Glossary http://mindprod.com
Roedy Green - 09 Oct 2007 05:05 GMT On Fri, 28 Sep 2007 02:28:00 -0700, Jerry Manner <goodminded@hotmail.com> wrote, quoted or indirectly quoted someone who said :
>I hav tried looking at the classes 'import java.text.NumberFormat' and >'import java.text.Format', but I didn't get far. see http://mindprod.com/jgloss/decimalformat.html
 Signature Roedy Green Canadian Mind Products The Java Glossary http://mindprod.com
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|