Question

I tried to work with easy example of java.util.Formatter class.

To my mind it works exactly as System.out.printf().

But my easy program show unexpected result.

Can smb explain why?

Expected is at the single line name of field: and value of this value.

Code:

class DataHolder {
    int i=145;
    long l = 789L;
    float f = 78.8F;
    double d = 34.9;

    public String toString() {
        StringBuilder sb = new StringBuilder("DataHolder class: \n\n");
        Formatter formatter = new Formatter(Locale.US);
        sb.append(formatter.format("int field: %d\n", i));
        sb.append(formatter.format("long field: %d\n", l));
        sb.append(formatter.format("float field: %f\n", f));
        sb.append(formatter.format("double field: %f\n", d));

        return sb.toString(); 
    }
}

public class Test {
    public static void main(String[] args) {
        System.out.println(new DataHolder());
    }
}

Output:

DataHolder class: 

int field: 145
int field: 145
long field: 789
int field: 145
long field: 789
float field: 78.800003
int field: 145
long field: 789
float field: 78.800003
double field: 34.900000

Why we can see here duplicates of lines, and some of them isn't correct.

What is wrong and how to work correctly with Formatter?

Was it helpful?

Solution

Each time you call format, it appends the given string, and then you append it to the StringBuffer. So after first call formatter will contain

int field: %d\n 

after second call:

int field: 145
long field: 789

and so on.

So its better to use formatter as a String buffer and the just to make to string:

formatter.format("int field: %d\n", i);
formatter.format("long field: %d\n", l);
formatter.format("float field: %f\n", f);
formatter.format("double field: %f\n", d);

OTHER TIPS

try

package com.linkage.test;

import java.util.Formatter;
import java.util.Locale;

class DataHolder {
    int i = 145;
    long l = 789L;
    float f = 78.8F;
    double d = 34.9;

    public String toString() {
        StringBuilder sb = new StringBuilder("DataHolder class: \n\n");
        Formatter formatter = new Formatter(Locale.US);
        sb.append(formatter.format("int field: %d\n", i));
        //this new object Formatter
        formatter = new Formatter(Locale.US);
        sb.append(formatter.format("long field: %d\n", l));
        //this new object Formatter
        formatter = new Formatter(Locale.US);
        sb.append(formatter.format("float field: %f\n", f));
        //this new object Formatter
        formatter = new Formatter(Locale.US);
        sb.append(formatter.format("double field: %f\n", d));
        return sb.toString();
    }
}

http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Formatter.html

From the JavaDoc

Writes a formatted string to this object's destination using the specified format string and arguments.

So, you are appending content to the formatter and invoking its toString() over and over again, which is why you are seeing:

  • Append 1: int
  • Append 2: int, long
  • Append 3: int, long, float
  • Append 4: int, long, float, double

What you should do instead is pass the StringBuilder as an argument to the Formatter and then print the StringBuilder at the end.

Hope that helps.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top