How do I properly align using String.format in Java? - java

Let's say I have a couple variable and I want to format them so they're all aligned, but the variables are different lengths. For example:
String a = "abcdef";
String b = "abcdefhijk";
And I also have a price.
double price = 4.56;
How would I be able to format it so no matter how long the String is, they are aligned either way?
System.out.format("%5s %10.2f", a, price);
System.out.format("%5s %10.2f", b, price);
For example, the code above would output something like this:
abcdef 4.56
abcdefhijk 4.56
But I want it to output something like this:
abcdef 4.56
abcdefhijk 4.56
How would I go about doing so? Thanks in advance.

Use fixed size format:
Using format strings with fixed size permits to print the strings in a
table-like appearance with fixed size columns:
String rowsStrings[] = new String[] {"1",
"1234",
"1234567",
"123456789"};
String column1Format = "%-3.3s"; // fixed size 3 characters, left aligned
String column2Format = "%-8.8s"; // fixed size 8 characters, left aligned
String column3Format = "%6.6s"; // fixed size 6 characters, right aligned
String formatInfo = column1Format + " " + column2Format + " " + column3Format;
for(int i = 0; i < rowsStrings.length; i++) {
System.out.format(formatInfo, rowsStrings[i], rowsStrings[i], rowsStrings[i]);
System.out.println();
}
Output:
1 1 1
123 1234 1234
123 1234567 123456
123 12345678 123456
In your case you could find the maximum length of the strings you want to display and use that to create the appropriate format information, for example:
// find the max length
int maxLength = Math.max(a.length(), b.length());
// add some space to separate the columns
int column1Length = maxLength + 2;
// compose the fixed size format for the first column
String column1Format = "%-" + column1Length + "." + column1Length + "s";
// second column format
String column2Format = "%10.2f";
// compose the complete format information
String formatInfo = column1Format + " " + column2Format;
System.out.format(formatInfo, a, price);
System.out.println();
System.out.format(formatInfo, b, price);

Put negative sign in front of your format specifier so instead of printing 5 spaces to the left of your float value, it adjusts the space on the right until you find the ideal position. It should be fine

You can achieve it as below-
String a = "abcdef";
String b = "abcdefhijk";
double price = 4.56;
System.out.println(String.format("%-10s %-10.2f", a, price));
System.out.println(String.format("%-10s %-10.2f", b, price));
output:
abcdef 4.56
abcdefhijk 4.56

You can find the longest String, and then use Apache commons-lang StringUtils to leftPad both of your String(s). Something like,
int len = Math.max(a.length(), b.length()) + 2;
a = StringUtils.leftPad(a, len);
b = StringUtils.leftPad(b, len);
Or, if you can't use StringUtils - you could implement leftPad. First a method to generate String of whitespace. Something like,
private static String genString(int len) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < len; i++) {
sb.append(' ');
}
return sb.toString();
}
Then use it to implement leftPad - like,
private static String leftPad(String in, int len) {
return new StringBuilder(in) //
.append(genString(len - in.length() - 1)).toString();
}
And, I tested it like,
int len = Math.max(a.length(), b.length()) + 2;
System.out.format("%s %.2f%n", leftPad(a, len), price);
System.out.format("%s %.2f%n", leftPad(b, len), price);
Which outputs (as I think you wanted)
abcdef 4.56
abcdefhijk 4.56

private String addEnoughSpacesInBetween(String firstStr, String secondStr){
if (!firstStr.isEmpty() && !secondStr.isEmpty()){
String space = " ";
int totalAllowed = 55;
int multiplyFor = totalAllowed - (firstStr.length() + secondStr.length());
return StringUtils.repeat(space,multiplyFor);
}
return null;
}

Related

Get the substring before the middle occurrence of a separator in java

I have a string bac/xaz/wed/rgc. I want to get the substring before and after the middle / in the string.
I don't find the solution with string split. how to achieve this? I am not sure if I have to use regex and split the string.
public static void main(String ...args) {
String value = "bac/xaz/wed/rgc/wed/rgc";
// Store all indexes in a list
List<Integer> indexList = new ArrayList<>();
for (int i = 0; i < value.length(); i++) {
if (value.charAt(i) == '/') {
indexList.add(i);
}
}
// Get the middle index from the list, works for odd number only.
int middleIndex = indexList.get(indexList.size() / 2);
System.out.println("First half: " + value.substring(0, middleIndex));
System.out.println("Second half: " + value.substring(middleIndex + 1));
}
Not an elegant solution, but it can handle as much '/' you gave it, as long as the total number of '/' is odd number.
Using an ArrayList might be overkill, but it works XD.
You can use split function to achieve that, using / as a delimiter:
String str = "bac/xaz/wed/rgc";
String[] arr = str.split('/');
You'll get an array of 4 strings: ["bac", "xaz", "wed", "rgc"].
From then on, you can retrieve the one that you want. If I understand well, you are interested in the elements 1 and 2:
String before = arr[1];
String after = arr[2];
If you meant to get the whole sub-string before the middle /, you can still concatenate the first two strings:
String strbefore = arr[0] + arr[1];
Same goes for the rest:
String strafter = arr[2] + arr[3];
here is a simple solution
String str = "bac/xaz/wed/rgc";
int loc = str.indexOf("/",str.indexOf('/')+1);
String str1 = str.substring(0,loc);
String str2 = str.substring(loc+1,str.length());
System.out.println(str1);
System.out.println(str2);
bac/xaz
wed/rgc

Algorithm to adding specific characters to specific places in a string

for example I have String: 61109010140000071219812874 and I want to apply algorithm, which will transofmation String in the following way:
611 09-010-14-000-00-712-19-812-87-4
as you can see, the point is to select the first three letters of the String, then add a white space, then add two dashes after two characters, then three, then again two characters. Something like:
### ##-###-##-###-##-###-##-###
Only I would like my algorithm to be universal. For example, for a string 6110901 output is: 611 09-01, for a string 61109010, output is: 611 09-010
I tried to use StringBuilder and the addCharAt method, but unfortunately it overwrites my string.
The above answers in the comments work but if you want a regular loop that builds what you want, this should do the trick:
public static void main(String args[]) {
String str = "61109010140000071219812874";
String output = "";
int segment = 2;
for(int i = 0; i < str.length(); i += segment){
segment = segment == 3 ? 2 : 3;
String seg = str.substring(i, Math.min(i + segment, str.length()));
char next = i == 0 ? ' ' : '-';
seg += next;
output += seg;
}
output = output.substring(0, output.length() - 1);
System.out.println(output); //611 09-010-14-000-00-712-19-812-87-4
}

How to display the characters upto a specific index of a String using String function?

I have my string defined as
text1:text2:text3:text4:text5
I want to get output as
text1:text2:text3
using String methods.
I have tried using lastIndexOf, then substring and then again lastIndexOf.
I want to avoid these three steps with calling lastIndexOf two times.
Is there a better way to achieve this?
You can do this by running a loop to iterate over the characters of the string from index = 0 to index = lastIndexOf('3'). Here's the code:
String s = "text1:text2:text3:text4:text5";
for(int i = 0; i < = s.lastIndexOf('3'); i++)
System.out.print(s.charAt(i));
This gives you the required output.
OUTPUT:
text1:text2:text3
A regular expression could be used to identify the correct part of the string:
private static Pattern PATTERN = Pattern.compile("([^:]*:){2}[^:]*(?=:|$)");
public static String find(String input) {
Matcher m = PATTERN.matcher(input);
return m.find() ? m.group() : null;
}
Alternatively do not use substring between every call of lastIndexOf, but use the version of lastIndexOf that restricts the index range:
public static String find(String input, int colonCount) {
int lastIndex = input.length();
while (colonCount > 0) {
lastIndex = input.lastIndexOf(':', lastIndex-1);
colonCount--;
}
return lastIndex >= 0 ? input.substring(0, lastIndex) : null;
}
Note that here colonCount is the number of : that are left out of the string.
You could try:
String test = "text1:text2:text3:text4:text5";
String splitted = text.split(":")
String result = "";
for (int i = 0; i <3; i++) {
result += splitted[i] + ":"
}
result = result.substring(0, result.length() -1)
You can use the Java split()-method:
String string = "text1:text2:text3:text4:text5";
String[] text = string.split(":");
String text1 = text[0];
String text2 = text[1];
String text3 = text[2];
And then generate the output directly or with a for-loop:
// directly
System.out.println(text1 + ":" + text2 + ":" + text3);
// for-loop. Just enter, how many elements you want to display.
for(int i = 0; i < 3; i++){
System.out.println(text[i] + " ");
}
Output:
text1 text2 text3
The advantage of using this method is, that your input and output can be a bit more complex, because you have power over the order in which the words can be printed.
Example:
Consider Master Yoda.
He has a strange way of talking and often mixes up the sentence structure. When he introduces himself, he says the (incorrect!) senctence: "Master Yoda my name is".
Now, you want to create an universal translator, that - of course - fixes those mistakes while translating from one species to another.
You take in the input-string and "divide" it into its parts:
String string = "Master:Yoda:my:name:is"
String[] text = string.split(":");
String jediTitle = text[0];
String lastName = text[1];
String posessivePronoun = text[2];
String noun = text[3];
String linkingVerb = text[4];
The array "text" now contains the sentence in the order that you put it in. Now your translator can analyze the structure and correct it:
String correctSentenceStructure = posessivePronoun + " " + noun + " " + linkingVerb + " " + jediTitle + " " + lastName;
System.out.println(correctSentenceStructure);
Output:
"My name is Master Yoda"
A working translator might be another step towards piece in the galaxy.
Maby try this one-line s.substring(0, s.lastIndexOf('3')+1);
Complete example:
package testing.project;
public class Main {
public static void main(String[] args) {
String s = "text1:text2:text3:text4:text5";
System.out.println(s.substring(0, s.lastIndexOf('3')+1));
}
}
Output:
text1:text2:text3

Android split by ' '

I want split a string for example: 5121321 in 5 121 321, every 3 is a ' '.
I have that code:
private void compor()
{
String dinheiro="5121321";
char aux[]= new char[dinheiro.length()];
for(int i=0;i<dinheiro.length();i++)
{
aux[i]=dinheiro.charAt(i);
}
int flag=0;
String total="";
for(int i=0;i<dinheiro.length();i++)
{
if(flag==3)
{
total+=' ';
flag=0;
}
total += String.valueOf(aux[i]);
flag++;
}
TextView txt = (TextView) findViewById(R.id.textView3);
txt.setText(String.valueOf(total));
}
The problem is the output of this is: 512 132 1 and i want 5 121 321. Sorry my english.
Somebody can help me?Thanks.
It looks like you're just trying to do general numeric formatting. A simple solution using framework utilities is:
public static String splitNumericString(String numeric) throws NumberFormatException {
// Create a new DecimalFormatSymbols instance and set the
// grouping separator to a space character
DecimalFormatSymbols symbols = new DecimalFormatSymbols();
symbols.setGroupingSeparator(' ');
// Construct a new NumberFormat defining a 3 digit grouping
// pattern
NumberFormat format = new DecimalFormat("#,###", symbols);
// Converts the string into an actual numeric value
long number = Long.parseLong(numeric);
// Return the formatted string
return format.format(number);
}
EDIT: Given #Squonk's info, this becomes a one-liner:
return NumberFormat.getInstance(Locale.FRANCE).format(Long.parseLong(numeric));
Although you should catch the NumberParseException in case of an improperly formatted input string.
(1) Just loop backwards through the string. And use pretty much the same idea you used. This will split it the way you want. (2) Alternatively, you can calculate where the first full triple starts by using the % (modulo) operator (I mean string length % 3).
Sample code for approach (2):
public class Test007 {
public static void main(String[] args) {
String dinheiro="5121322";
int i = dinheiro.length() % 3;
String s1 = "";
s1 = dinheiro.substring(0, i);
String s2 = "";
for (int k=i; k<dinheiro.length(); k+=3){
if (k!=i || i>0){
s2 += " ";
}
s2 += dinheiro.substring(k, k+3);
}
System.out.println(s1 + s2);
}
}
Instead of catenating in a loop, use a stringbuilder:
String input = /*...*/;
StringBuilder sb = new StringBuilder();
int i = 2;
for (char c : input.toCharArray()) {
sb.append(c);
i++;
if (i == 3) {
sb.append(' ');
i = 0;
}
}
String result = sb.toString();
Here's a variant to Peter Petrov's solution:
public static String group(String in) {
// Get the length of the first group
int i = (in.length() - 1) % 3 + 1;
// Add the first group
String out = in.substring(0, i);
// Add the other groups, each prefixed with a space
for (int k = i; k < in.length(); k += 3){
out += " " + in.substring(k, k + 3);
}
return out;
}
We get the length of the first group, we initialize the output with that first group and then we go over the remainder of the input to append one group of 3 digits at a time. That's really all there is to it.
The tricky bit is in the first line. Just using in.length() % 3 doesn't work correctly, since that prevents the first group from ever having 3 digits. For example, an input of "123456" would lead to i == 0 and an output of " 123 456" (note the unwanted space at the start). Peter uses an if check to deal with this case, but it turns out you can also handle it by changing i a bit.
We want the relation between in.length() and i to be like this:
in.length() | i | (in.length() - 1) % 3
------------------------------------------
0 | 0 | -1
1 | 1 | 0
2 | 2 | 1
3 | 3 | 2
4 | 1 | 0
5 | 2 | 1
... | ... | ...
Subtracting one before the modulo and adding it back afterwards gives us this relation (the partial result after the modulo is in the third column). It even handles the special case where in is the empty string! :-P
The solution is easier to write with simple arithmetic than with string manipulation:
public static String groupDigits(int amount) {
String total = "";
while (amount > 0) {
Integer digits = amount % 1000;
amount = amount / 1000;
total = digits.toString() + " " + total;
}
return total;
}

Left padding a String with Zeros [duplicate]

This question already has answers here:
How can I pad a String in Java?
(32 answers)
Closed 5 years ago.
I've seen similar questions here and here.
But am not getting how to left pad a String with Zero.
input: "129018"
output: "0000129018"
The total output length should be TEN.
If your string contains numbers only, you can make it an integer and then do padding:
String.format("%010d", Integer.parseInt(mystring));
If not I would like to know how it can be done.
String paddedString = org.apache.commons.lang.StringUtils.leftPad("129018", 10, "0")
the second parameter is the desired output length
"0" is the padding char
This will pad left any string to a total width of 10 without worrying about parse errors:
String unpadded = "12345";
String padded = "##########".substring(unpadded.length()) + unpadded;
//unpadded is "12345"
//padded is "#####12345"
If you want to pad right:
String unpadded = "12345";
String padded = unpadded + "##########".substring(unpadded.length());
//unpadded is "12345"
//padded is "12345#####"
You can replace the "#" characters with whatever character you would like to pad with, repeated the amount of times that you want the total width of the string to be. E.g. if you want to add zeros to the left so that the whole string is 15 characters long:
String unpadded = "12345";
String padded = "000000000000000".substring(unpadded.length()) + unpadded;
//unpadded is "12345"
//padded is "000000000012345"
The benefit of this over khachik's answer is that this does not use Integer.parseInt, which can throw an Exception (for example, if the number you want to pad is too large like 12147483647). The disadvantage is that if what you're padding is already an int, then you'll have to convert it to a String and back, which is undesirable.
So, if you know for sure that it's an int, khachik's answer works great. If not, then this is a possible strategy.
String str = "129018";
String str2 = String.format("%10s", str).replace(' ', '0');
System.out.println(str2);
String str = "129018";
StringBuilder sb = new StringBuilder();
for (int toPrepend=10-str.length(); toPrepend>0; toPrepend--) {
sb.append('0');
}
sb.append(str);
String result = sb.toString();
You may use apache commons StringUtils
StringUtils.leftPad("129018", 10, "0");
https://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/StringUtils.html#leftPad(java.lang.String,%20int,%20char)
To format String use
import org.apache.commons.lang.StringUtils;
public class test {
public static void main(String[] args) {
String result = StringUtils.leftPad("wrwer", 10, "0");
System.out.println("The String : " + result);
}
}
Output : The String : 00000wrwer
Where the first argument is the string to be formatted, Second argument is the length of the desired output length and third argument is the char with which the string is to be padded.
Use the link to download the jar http://commons.apache.org/proper/commons-lang/download_lang.cgi
If you need performance and know the maximum size of the string use this:
String zeroPad = "0000000000000000";
String str0 = zeroPad.substring(str.length()) + str;
Be aware of the maximum string size. If it is bigger then the StringBuffer size, you'll get a java.lang.StringIndexOutOfBoundsException.
An old question, but I also have two methods.
For a fixed (predefined) length:
public static String fill(String text) {
if (text.length() >= 10)
return text;
else
return "0000000000".substring(text.length()) + text;
}
For a variable length:
public static String fill(String text, int size) {
StringBuilder builder = new StringBuilder(text);
while (builder.length() < size) {
builder.append('0');
}
return builder.toString();
}
I prefer this code:
public final class StrMgr {
public static String rightPad(String input, int length, String fill){
String pad = input.trim() + String.format("%"+length+"s", "").replace(" ", fill);
return pad.substring(0, length);
}
public static String leftPad(String input, int length, String fill){
String pad = String.format("%"+length+"s", "").replace(" ", fill) + input.trim();
return pad.substring(pad.length() - length, pad.length());
}
}
and then:
System.out.println(StrMgr.leftPad("hello", 20, "x"));
System.out.println(StrMgr.rightPad("hello", 20, "x"));
Use Google Guava:
Maven:
<dependency>
<artifactId>guava</artifactId>
<groupId>com.google.guava</groupId>
<version>14.0.1</version>
</dependency>
Sample code:
Strings.padStart("129018", 10, '0') returns "0000129018"
Based on #Haroldo MacĂȘdo's answer, I created a method in my custom Utils class such as
/**
* Left padding a string with the given character
*
* #param str The string to be padded
* #param length The total fix length of the string
* #param padChar The pad character
* #return The padded string
*/
public static String padLeft(String str, int length, String padChar) {
String pad = "";
for (int i = 0; i < length; i++) {
pad += padChar;
}
return pad.substring(str.length()) + str;
}
Then call Utils.padLeft(str, 10, "0");
Here's another approach:
int pad = 4;
char[] temp = (new String(new char[pad]) + "129018").toCharArray()
Arrays.fill(temp, 0, pad, '0');
System.out.println(temp)
Here's my solution:
String s = Integer.toBinaryString(5); //Convert decimal to binary
int p = 8; //preferred length
for(int g=0,j=s.length();g<p-j;g++, s= "0" + s);
System.out.println(s);
Output: 00000101
Right padding with fix length-10:
String.format("%1$-10s", "abc")
Left padding with fix length-10:
String.format("%1$10s", "abc")
Here is a solution based on String.format that will work for strings and is suitable for variable length.
public static String PadLeft(String stringToPad, int padToLength){
String retValue = null;
if(stringToPad.length() < padToLength) {
retValue = String.format("%0" + String.valueOf(padToLength - stringToPad.length()) + "d%s",0,stringToPad);
}
else{
retValue = stringToPad;
}
return retValue;
}
public static void main(String[] args) {
System.out.println("'" + PadLeft("test", 10) + "'");
System.out.println("'" + PadLeft("test", 3) + "'");
System.out.println("'" + PadLeft("test", 4) + "'");
System.out.println("'" + PadLeft("test", 5) + "'");
}
Output:
'000000test'
'test'
'test'
'0test'
The solution by Satish is very good among the expected answers. I wanted to make it more general by adding variable n to format string instead of 10 chars.
int maxDigits = 10;
String str = "129018";
String formatString = "%"+n+"s";
String str2 = String.format(formatString, str).replace(' ', '0');
System.out.println(str2);
This will work in most situations
int number = -1;
int holdingDigits = 7;
System.out.println(String.format("%0"+ holdingDigits +"d", number));
Just asked this in an interview........
My answer below but this (mentioned above) is much nicer->
String.format("%05d", num);
My answer is:
static String leadingZeros(int num, int digitSize) {
//test for capacity being too small.
if (digitSize < String.valueOf(num).length()) {
return "Error : you number " + num + " is higher than the decimal system specified capacity of " + digitSize + " zeros.";
//test for capacity will exactly hold the number.
} else if (digitSize == String.valueOf(num).length()) {
return String.valueOf(num);
//else do something here to calculate if the digitSize will over flow the StringBuilder buffer java.lang.OutOfMemoryError
//else calculate and return string
} else {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < digitSize; i++) {
sb.append("0");
}
sb.append(String.valueOf(num));
return sb.substring(sb.length() - digitSize, sb.length());
}
}
Check my code that will work for integer and String.
Assume our first number is 129018. And we want to add zeros to that so the the length of final string will be 10. For that you can use following code
int number=129018;
int requiredLengthAfterPadding=10;
String resultString=Integer.toString(number);
int inputStringLengh=resultString.length();
int diff=requiredLengthAfterPadding-inputStringLengh;
if(inputStringLengh<requiredLengthAfterPadding)
{
resultString=new String(new char[diff]).replace("\0", "0")+number;
}
System.out.println(resultString);
I have used this:
DecimalFormat numFormat = new DecimalFormat("00000");
System.out.println("Code format: "+numFormat.format(123));
Result: 00123
I hope you find it useful!

Categories