String.format() get maximum value

2019-08-30 23:36发布

问题:

I implemented a counter method that returns always an incremented number. But the user can give wished format, 2 digits, 3 digits or whatever he wants. The format is the standard String.format() type of String like %02d or %5d. When the maximum value is reached, the counter should be reset to 0.

How can I find out the max value that can be represented with the given format?

int counter = 0;
private String getCounter(String format){
    if(counter >= getMaximum(format)){
        counter = 0;
    }
    else {
        counter++;
    }
    return String.format(format, counter);
}

private int getMaximum(String format){
    //TODO ???
    //Format can be %02d => should return 100
    //Format can be %05d => should return 100000

}

回答1:

Haven't validated this code, but something along the lines of this should work with erro checking in place

    String str = fullresultText.replace ("%", "").replace("d", "");
    maxVal = Math.pow (10, Integer.parseInt (str));


回答2:

private int counter = 0;

private String getCounter(String format) {
    counter = (counter + 1) % getMaximum(format);
    return String.format(format, counter);
}

private int getMaximum(String format) {
    try {
        MessageFormat messageFormat = new MessageFormat("%{0,number,integer}d");
        int pow = ((Long) messageFormat.parse(format)[0]).intValue();
        return (int) Math.pow(10, pow);
    } catch (ParseException e) {
        System.out.println("Incorrect format");
        return -1;
    }
}


回答3:

There is nothing builtin for this, and I'm not aware of any libraries that do this (I could be wrong). Remember that formats will expand if necessary to avoid losing digits. For example

System.out.printf("%06d", 11434235);

will happily print the entire 8-digit number.

So specifying the format directly is probably not the right approach. Create a Counter class to encapsulate the desired "odometer" behavior.

public class Counter {
    private int width;
    private int limit;
    private String format;
    private int value=0;
    public Counter(int width, int value) { 
        this.width  = width; 
        this.limit  = BigInteger.valueOf(10).pow(width).intValue()-1; 
        this.format = String.format("%%0%dd",width);
        this.value  = value;
    }
    public Counter(int width) {
        this(width,0);
    }
    public Counter increment() { 
        value = value<limit ? value+1 : 0;
        return this; 
    }
    @Override
    public String toString() {
        return String.format(this.format,this.value); 
    }
}

Sample usage:

Counter c3 = new MiscTest.Counter(3,995);
for (int i=0; i<10; i++)
{
    System.out.println(c3.increment().toString());
}

Output:

996
997
998
999
000
001
002
003
004
005