LTH
LTH

Reputation: 1839

Formatting String in Java?

I'm coding a class that's supposed to model airplane cargo and I'm having trouble formatting the class's toString() method. The following code:

public class Cargo 
{
    private String label;
    private int weight, height, width, length;

    public String toString()
    {
        return String.format("%s%s\t\t%-7s%-2s%-5d%-11s%-2s%-3d%-2s%-3d%-2s%d",
                getLabel(), ":", "Weight", "=", getWeight(), "Dimensions",
                "=", getHeight(), "X", getWidth(), "X", getLength());
    }

    public static void main(String[] args)
    {
        Cargo cargo1 = new Cargo("Bill's Beans", 1200, 20, 15, 30);
        Cargo cargo6 = new Cargo("Chicago Bulls", 1000, 10, 10, 10);
        Cargo cargo7 = new Cargo("Lots of Meat", 3000, 20, 20, 20);
        Cargo cargo8 = new Cargo("Tammy's Tomatoes", 600, 6, 6, 6);

        System.out.println(cargo1.toString());
        System.out.println(cargo6.toString());
        System.out.println(cargo7.toString());
        System.out.println(cargo8.toString());
    }
}

Produces this output:

Bill's Beans:       Weight = 1200 Dimensions = 20 X 15 X 30
Chicago Bulls:      Weight = 1000 Dimensions = 10 X 10 X 10
Lots of Meat:       Weight = 3000 Dimensions = 20 X 20 X 20
Tammy's Tomatoes:       Weight = 600  Dimensions = 6  X 6  X 6

As you can see, everything aligns well, except for "Tammy's Tomatoes." How can I fix this? Thanks.

Upvotes: 1

Views: 591

Answers (2)

eboix
eboix

Reputation: 5133

It all aligns well except for "Tammy's Tomatoes" because you're using tabs. In this case, your tabs are 4 characters long. While "Bill's Beans:" is 13 characters, "Chicago Bulls:" is 14, and "Lots of Meat:" is 13, "Tammy's Tomatoes:" is 17.

13/4 = 3
14/4 = 3
13/4 = 3
17/4 = 4

Or at least that's what programmers think ;)

So when you put another tab on the last, one, it starts 4 characters after the rest.

You can fix this by adjusting the number of tabs depending on how many characters the names of the companies have.

Say that you want the dimensions to start at the 7th set of 4 spaces.

First, calculate the amount of spaces the names will occupy. Divide by four (as I did above).

Subtract the number from 7. So Tammy's Tomatoes would be 7-4=3. Run a loop adding 3 "\t"'s to the result (where you want to add them).

So in the end, your code would look like this:

    String result = String.format("%s%s", getLabel(), ":");

    int tabs = result.length()/4;
    int desiredTabs = 7;
    for(int i = 0; i < desiredTabs-tabs) {
        result += "\t";
    }
    result += String.format("%-7s%-2s%-5d%-11s%-2s%-3d%-2s%-3d%-2s%d",
            "Weight", "=", getWeight(), "Dimensions",
            "=", getHeight(), "X", getWidth(), "X", getLength());
    return result;

EDIT to answer question in comment:

Well, you don't really need to use String.format(). You can actually just append the variables (for example, result + getWidth()). I just used String.format() because that was what you had used. You could rewrite it to:

    String result = String.format("%s%s", getLabel(), ":");

    int tabs = result.length()/4;
    int desiredTabs = 7;
    for(int i = 0; i < desiredTabs-tabs) {
        result += "\t";
    }
    result += "Weight = " + getWeight() + " Dimensions = " + getHeight() + " X " + getWidth() + " X " + getLength();

    return result;

Much simpler :)

Upvotes: 5

arcy
arcy

Reputation: 13103

I would actually recommend staying away from tabs. There are going to be situations in which programs output to places that have different tab settings, and depending on tabs for aligning output is a dodgy prospect in the general case for exactly the reason you've already run into. -- aligning things depends on knowing (or calculating) the length of the data you are separating with them. In your case, if you end up with a label that is over 28 characters long, your calculation is going to fail.

Why not just use the width flag of the fields to specify the width of the label, instead of using tabs?

Separately, and just as a suggestion, I also find the format string easier to read (and create!) if it just has the constants embedded in it:

String formatString = "%17s: Weight = %-5d Dimensions = %-2d X %-2d X %-2d";
String result = String.format(formatString, getWeight(), getHeight(), getWidth(), getLength());

Now, when I look at the string, it is easier for me to tell where I'm putting data and what the overall result will look like, instead of attempting to match up constants with their formatting strings.

Anyway, it's an alternative.

Upvotes: 2

Related Questions