Formatting a string in Java

Discussion in 'Java' started by Jerry Manner, Sep 28, 2007.

  1. Jerry Manner

    Jerry Manner Guest

    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
     
    Jerry Manner, Sep 28, 2007
    #1
    1. Advertisements

  2. 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.
     
    Jean-Baptiste Nizet, Sep 28, 2007
    #2
    1. Advertisements

  3. 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.
     
    Lionel van den Berg, Sep 28, 2007
    #3
  4. Jerry Manner

    Jerry Manner Guest

    Hi

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

    Kind Regards
     
    Jerry Manner, Sep 28, 2007
    #4
  5. Why not

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

    ?

    Juergen
     
    =?iso-8859-1?q?J=FCrgen_Gerstacker?=, Sep 28, 2007
    #5
  6. 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.
     
    Jean-Baptiste Nizet, Sep 28, 2007
    #6
  7. Jerry Manner

    Lew Guest

    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.
     
    Lew, Sep 28, 2007
    #7
  8. 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, Sep 28, 2007
    #8
  9. Jerry Manner

    Lew Guest

    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".
     
    Lew, Sep 28, 2007
    #9
  10. Jerry Manner

    Lew Guest

    equivalent to
    StringBuilder sb = new StringBuilder();

    but I wanted to make the intent here crystal clear.
     
    Lew, Sep 28, 2007
    #10
  11. 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.
     
    Jean-Baptiste Nizet, Sep 28, 2007
    #11
  12. 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.
     
    Lionel van den Berg, Sep 28, 2007
    #12
  13. Jerry Manner

    Lew Guest

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

    Can we say, "supercilious"?
    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.
     
    Lew, Sep 29, 2007
    #13
  14. Jerry Manner

    Lew Guest

    Can we say, "supercilious"?

    Yes, you are right. I reviewed the text and corrected my interpretation.
     
    Lew, Sep 29, 2007
    #14
  15. Jerry Manner

    Lew Guest

    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.
     
    Lew, Sep 29, 2007
    #15
  16. Jerry Manner

    Roedy Green Guest

    you could write that more simply as
     
    Roedy Green, Sep 29, 2007
    #16
  17. Jerry Manner

    Roedy Green Guest


    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.
     
    Roedy Green, Sep 29, 2007
    #17
  18. 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
     
    =?ISO-8859-1?Q?Arne_Vajh=F8j?=, Oct 9, 2007
    #18
  19. Jerry Manner

    Roedy Green Guest

    Roedy Green, Oct 9, 2007
    #19
  20. [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
     
    Chris ( Val ), Oct 9, 2007
    #20
    1. Advertisements

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 (here). After that, you can post your question and our members will help you out.