Formatting a string in Java

J

Jerry Manner

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
 
J

Jean-Baptiste Nizet

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?

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

Lionel van den Berg

Jean-Baptiste Nizet said:
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();
}
}

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

Jerry Manner

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.

Hi

Thank you very much. Your tip helped me alot. Up to the next challenge
for me :)

Kind Regards
 
?

=?iso-8859-1?q?J=FCrgen_Gerstacker?=

Why not

String.format("%05d", 5);
String.format("%05d", 23);

?

Juergen
 
J

Jean-Baptiste Nizet

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;

}

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

Lew

Lionel said:
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.
 
J

Jean-Baptiste Nizet

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

Lew

Jean-Baptiste Nizet said:
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".
 
J

Jean-Baptiste Nizet

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

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

Lionel van den Berg

Jean-Baptiste Nizet said:
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.

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

Lew

Note the String creation inside the loop, which we should seek to avoid, no?

Jean-Baptiste Nizet said:
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.

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:
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.
 
L

Lew

Jean-Baptiste Nizet said:
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.

Can we say, "supercilious"?

Yes, you are right. I reviewed the text and corrected my interpretation.
 
L

Lew

Jean-Baptiste Nizet said:
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.

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

=?ISO-8859-1?Q?Arne_Vajh=F8j?=

Jerry 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".

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?

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
 
C

Chris ( Val )

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 aString?
StringBuilder sb = new StringBuilder( "" );
while ( len++ < 5 )
{
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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top