Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / October 2007

Tip: Looking for answers? Try searching our database.

Formatting a string in Java

Thread view: 
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 Magazines

Get 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 ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.