问题描述:

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?

网友答案:

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);
网友答案:

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.

相关阅读:
Top