How can we set dynamic width and precision while formatting string? I know the following code works good, but how can we do it in a formatter way?
int len = 3;
String s = "Andy";
System.out.printf("%1$" + len + "." + len + "s%n", s);
Output:
And
I have tried this one. It didn't throw an error, but prints different value than expected. (It looks so messy, but I've tried to pass the 'len' to width and precision. That's it. :) )
System.out.printf("%2$%1$d.%1$ds%n", len, s);
Output:
%1$d.3s
Is it doable? If so, how can we get same output as the former one?
Unfortunatly, the formatter used in String.format read the String from left to right, so it doesn't notice the new flag generated. This would have been possible if it will read from right to left but the problem would have been with the varags since you can pass to many parameters to the methods.
So the only way to format something like
String.format("|%ds", 5, "foo")
to output
| foo
Would be to format twice, this would not be the most effecient but the most readable (and that not even really true ......)
So my solution looks like this
String.format(String.format("|%%%ds", 5), "foo") //Here, I add a double %
the first formatter will return %5s that will be format again with the String.
Related
I am using Poi to create Excel workbooks in Java. My raw data comes in as a string. I need to format the data to enter two decimal places into the cell where the number is being written. I use Double.parseDouble() to convert the string to numeric and then use DecimalFormat to format the numeric as a string. Another call to Double.parseDouble() to return the value to numeric (the cell where it is going is formatted numeric, so I can't use the string value) and I should be good. Problem is, that second call to Double.parseDouble() truncates any trailing zeroes off from the right of the decimal point. Anybody have an idea as to how I can coerce this value to read as, say, 1.50 rather than 1.5?
I always want two decimals.
Solution: Always apply specific decimal format pattern.
Sample code snippet:
//java.text.DecimalFormat df = new java.text.DecimalFormat( "###0.00" );
java.text.DecimalFormat df = new java.text.DecimalFormat();
df.applyPattern( "###0.00" ); // always two decimals
double dbl = 1.50d ;
// prints: dbl = 1.5
System.out.println( "dbl = " + dbl );
// prints: df.format( 1.5 ) = 1.50
System.out.println ( "df.format( " + dbl + " ) = " + df.format( dbl ) );
UPDATE:
OK, from your posting, I understand that you are trying to fill the numeric formatted cell only to print or show up with two decimal positions. You know by default all numeric fields are interpreted omitting trailing zeros. To achieve your requirement, you may require to use CellFormat and/or DataFormatter on your contextual Cell object, but when said Format, it is a String again.
I didn't try the following code but may help you.
DataFormatter dataFormatter = new DataFormatter();
dataFormatter.setDefaultNumberFormat( instanceOfDesiredDecimalFormat );
// or
// dataFormatter.setExcelStyleRoundingMode( instanceOfDesiredDecimalFormat );
// apply this format on the cell you want
dataFormatter.formatCellValue( instanceOfNumericCellInContext );
You are actually doing nothing in most part of the code you described. You might as well just return Double.parseDouble(inputString). Doubles are stored in binary format and the leadin/trailing zeros make no sense. Perhaps the BigDecimal class is something for you.
It appears we are at an impasse. As Mario pointed out, doubles are managed as binary and there is no way to format the binary as a double, except to convert it to a string with DecimalFormat, which is no longer a double. I explained this to my boss and he's ok with the solution of taking the raw double, so I'm closing this issue. Thanks to all for your help and support.
regards,
Mike
I'm trying to format the numbers to look like a certain way.
So, I have like the number 1007,2, and I want it to look like 1 007,20
This has two factors needed:
Thousands format
Two decimal places
I have a code that sets the thousands format:
Double total_value = Double.valueOf(1007,2);
String formatedValue = NumberFormat.getNumberInstance(Locale.CANADA_FRENCH).format(total_value);
And the output is:
1 007,2€
And I have the code for the two decimal places:
Double total_value = Double.valueOf(1007,2);
String formatedValue = String.format("%.2f", total_value);
The problem is, for using this two format methods at the same time they get always problems, because the two of them return Strings, and both need to receive the values for formatting in Double.
If I receive one in String, when I try to parse the String to Double like String value = Double.parseDouble(formatedValue);or String value = Double.valueOf(formatedValue) they always get an error. I've already tried the DecimalFormat to but it returns a String too.
So, I dont know how to do to conjugue the two methods to work together!
If you have any idea please comment it :)
You don't want to combine NumberFormat and String.format().
You can further configure your NumberFormat object to tell it to use two decimal places:
NumberFormat numberFormat = NumberFormat.getNumberInstance(Locale.CANADA_FRENCH);
numberFormat.setMinimumFractionDigits(2);
assertThat(numberFormat.format(1007.2), is("1 007,20"));
(and possibly setMaximumFractionDigits() etc., depending on your needs -- see the Javadoc)
Take care - NumberFormat.format() is not thread-safe.
Alternatively you can use String.format(locale, format, args):
assertThat(String.format(Locale.CANADA_FRENCH, "%,.2f", 1007.2), is("1 007,20"));
The , flag in the format tells the formatter to use a thousands-separator, and the locale tells it that the separator is a space.
After setting the thousand format you could do someting like:
String[] splitter = formatedValue.split("\\,");
int decimalDigits = 0;
if (splitter.length > 1) {
formatedValue = splitter[1].length();
} else {
formatedValue += ",";
}
for (int i = 0; i < 2 - decimalDigits; i++) {
formatedValue += "0";
}
I have not tested this, and it is not the really pretty, but i am using something similar for the english format.
To make sure you have only two decimal digits you should probably round your total value at the beginning.
A normal scoreboard text is like this
so i want to make te text format like this
this is the code
score = (TextView)findViewById(R.id.ct);
score.setText(String.valueOf(gamescore));
if (gamescore > highscore){
high.setText(String.valueOf(gamescore));
}
Anyone can explain? Thank's
You should use the String.format() method along with the formatter syntax. String.format() can be used to left-pad a string with zeroes, just like you want.
This code will give you the results that you want: high.setText(String.format("%06d", gamescore));
Let's look at what's going on in detail. We are using this syntax: %[flags][width]conversion
Always begin the format string syntax with a %.
Following % is 0, the zero-padding flag. This tells the formatter that the result will be zero-padded.
After the zero-padding flag is the width, or the minimum number of digits we want; in this case, 6.
Lastly, specify the conversion type. The desired result is formatted as a decimal integer, so we use d.
Here is an example:
int gamescore = 100;
String result = String.format("%06d", gamescore);
System.out.println(result);
Output: 000100
Integer.toBinaryString(data)
gives me a binary String representation of my array data.
However I would like a simple way to add leading zeros to it, since a byte array equal to zero gives me a "0" String.
I'd like a one-liner like this:
String dataStr = Integer.toBinaryString(data).equals("0") ? String.format(format, Integer.toBinaryString(data)) : Integer.toBinaryString(data);
Is String.format() the correct approach? If yes, what format String should I use?
Thanks in advance!
Edit: The data array is of dynamic length, so should the number of leading zeros.
For padding with, say, 5 leading zeroes, this will work:
String.format("%5s", Integer.toBinaryString(data)).replace(' ', '0');
You didn't specify the expected length of the string, in the sample code above I used 5, replace it with the proper value.
EDIT
I just noticed the comments. Sure you can build the pattern dynamically, but at some point you have to know the maximum expected size, depending on your problem, you'll know how to determine the value:
String formatPattern = "%" + maximumExpectedSize + "s";
This is what you asked for—padding is added only when the value is zero.
String s = (data == 0) ? String.format("%0" + len + 'd', 0) : Integer.toBinaryString(data);
If what you really want is for all binary values to be padded so that they are the same length, I use something like this:
String pad = String.format("%0" + len + 'd', 0);
String s = Integer.toBinaryString(data);
s = pad.substring(s.length()) + s;
Using String.format() directly would be the best, but it only supports decimal, hexadecimal, and octal, not binary.
You could override that function in your own class:
public static String toBinaryString(int x){
byte[] b = new byte[32]; // 32 bits per int
int pos = 0;
do{
x = x >> 1; // /2
b[31-pos++] = (byte)(x % 2);
}while(x > 0);
return Arrays.toString(b);
}
would this satisfy your needs?
String dataStr = data == 0 ? "00" + Integer.toBinaryString(data) : Integer.toBinaryString(data);
edit: noticed the comment about dynamic length:
probably some of the other answers are more suited:)
This, in concept, is almost same as #Óscar López answer, but different methods are used, so i thought i should post it. Hope this is fine.
1] Building the format string
String format = "%0" + totalDigits + "d";
2] Integer to Binary Conversion
String dataStr = Integer.toBinaryString(data);
3] Padding with Leading Zeros
dataStr = String.format(format, new Integer(dataStr));
The major difference here is the 3rd step. I believe, its actually a hack.
#erickson is right in String.format() not supporting binary, hence, i converted the binary number to an integer (not its equivalent), i.e., "100" will be converted to hundred (100), not four(4). I then used normal formatting.
Not sure about how much optimized this code is, but, i think its more easy to read, but, maybe, its just me.
EDIT
1] Buffer Over-run is possible for longer binary strings. Long can be used, but, even that has limitations.
2] BigInteger can be used, but, I'm sure, it will be the costliest at runtime compared to all the other methods.
So, it seems, unless only shorter binary strings are expected, replace() is the better method.
Seniors,
please correct me if I'm wrong.
Thanks.
I want to transform an int to a String such that:
0 -> "a"
1 -> "b"
2 -> "c"
and so on...
How can I do this?
You can convert from the character literal:
int input = 0;
String output = new Character((char) (input + 'a')).toString();
Your question is a little unclear, but it sounds like you want to be able to convert integers 0-25 to their corresponding alphabetical characters. If that's the case, your best bet logically is probably to use an enum. Though I may not be fully seeing the purpose of what you're trying to do (which is likely).
You could also write a utility method which just has a big switch statement to convert them.
An alternate method, for some java library flavor:
int value;
String output = Integer.toString(value + 10, 36);
which uses a radix of 36 to locate the right letter.