I have a special table in my database where I store the message key - value in the form, for example: question first - How are you, ...?
Now I want to insert for example a name at the end of the question. I don't need a hardcode, I want to do it through some formatting. I know that there is an option to insert text through % or ?1 - but I don't know how to apply this in practice. How are you, % or (?1)?
And what if I need to insert text not only at the end, but also in the random parts:
Hey, (name)! Where is your brother, (brothers name)?
You can insert a String into another String using the String.format() method. Place a %s anywhere in the String where you want and then follow the below syntax. More information here.
String original = "Add to this pre-existing String";
String newString = String.format("Add %s to this pre-existing String", "words");
// original = "Add to this pre-existing String"
// newString = "Add words to this pre-existing String"
In your specific situation, you can store the names as other Strings and do this:
String name = "anyName";
String brothers_name = "anyBrotherName";
String formattedString = String.format("Hey, %s! Where is your brother, %s?", name, brothers_name);
How about this?
String.format("Hey, %s! Where is your brother, %s?","Sally", "Johnny");
For using the %, first you will need to create another variable of type string in which you store the text you want to print.
Example:
String a="Alice";
String b="Bob";
String str=string.format("Hey, %s! Where is your brother, %s?"a,b);
System.out.println(str);
Output:
Hey Alice! Where is your brother, Bob?
You can get more information about this here
Related
I am setting text using setText() by following way.
prodNameView.setText("" + name);
prodOriginalPriceView.setText("" + String.format(getString(R.string.string_product_rate_with_ruppe_sign), "" + new BigDecimal(price).setScale(2, RoundingMode.UP)));
In that First one is simple use and Second one is setting text with formatting text.
Android Studio is so much interesting, I used Menu Analyze -> Code Cleanup and i got suggestion on above two lines like.
Do not concatenate text displayed with setText. Use resource string
with placeholders. less... (Ctrl+F1)
When calling TextView#setText:
Never call Number#toString() to format numbers; it will not handle fraction separators and locale-specific digits properly. Consider
using String#format with proper format specifications (%d or %f)
instead.
Do not pass a string literal (e.g. "Hello") to display text. Hardcoded text can not be properly translated to other languages.
Consider using Android resource strings instead.
Do not build messages by concatenating text chunks. Such messages can not be properly translated.
What I can do for this? Anyone can help explain what the thing is and what should I do?
Resource has the get overloaded version of getString which takes a varargs of type Object: getString(int, java.lang.Object...). If you setup correctly your string in strings.xml, with the correct place holders, you can use this version to retrieve the formatted version of your final String. E.g.
<string name="welcome_messages">Hello, %1$s! You have %2$d new messages.</string>
using getString(R.string.welcome_message, "Test", 0);
android will return a String with
"Hello Test! you have 0 new messages"
About setText("" + name);
Your first Example, prodNameView.setText("" + name); doesn't make any sense to me. The TextView is able to handle null values. If name is null, no text will be drawn.
Don't get confused with %1$s and %2$d in the accepted answer.Here is a few extra information.
The format specifiers can be of the following syntax:
%[argument_index$]format_specifier
The optional argument_index is specified as a number ending with a “$” after the “%” and selects the specified argument in the argument list. The first argument is referenced by "1$", the second by "2$", etc.
The required format specifier is a character indicating how the argument should be formatted. The set of valid conversions for a given argument depends on the argument's data type.
Example
We will create the following formatted string where the gray parts are inserted programmatically.
Hello Test! you have 0 new messages
Your string resource:
< string name="welcome_messages">Hello, %1$s! You have %2$d new
messages< /string >
Do the string substitution as given below:
getString(R.string.welcome_message, "Test", 0);
Note:
%1$s will be substituted by the string "Test"
%2$d will be substituted by the string "0"
I ran into the same lint error message and solved it this way.
Initially my code was:
private void displayQuantity(int quantity) {
TextView quantityTextView = (TextView) findViewById(R.id.quantity_text_view);
quantityTextView.setText("" + quantity);
}
I got the following error
Do not concatenate text displayed with setText. Use resource string with placeholders.
So, I added this to strings.xml
<string name="blank">%d</string>
Which is my initial "" + a placeholder for my number(quantity).
Note: My quantity variable was previously defined and is what I wanted to append to the string. My code as a result was
private void displayQuantity(int quantity) {
TextView quantityTextView = (TextView) findViewById(R.id.quantity_text_view);
quantityTextView.setText(getString(R.string.blank, quantity));
}
After this, my error went away. The behavior in the app did not change and my quantity continued to display as I wanted it to now without a lint error.
Do not concatenate text inside your setText() method, Concatenate what ever you want in a String and put that String value inside your setText() method.
ex: correct way
int min = 120;
int sec = 200;
int hrs = 2;
String minutes = String.format("%02d", mins);
String seconds = String.format("%02d", secs);
String newTime = hrs+":"+minutes+":"+seconds;
text.setText(minutes);
Do not concatenate inside setText() like
text.setText(hrs+":"+String.format("%02d", mins)+":"+String.format("%02d", secs));
You should check this thread and use a placeholder like his one (not tested)
<string name="string_product_rate_with_ruppe_sign">Price : %1$d</string>
String text = String.format(getString(R.string.string_product_rate_with_ruppe_sign),new BigDecimal(price).setScale(2, RoundingMode.UP));
prodOriginalPriceView.setText(text);
Don't Mad, It's too Simple.
String firstname = firstname.getText().toString();
String result = "hi "+ firstname +" Welcome Here";
mytextview.setText(result);
the problem is because you are appending "" at the beginning of every string.
lint will scan arguments being passed to setText and will generate warnings, in your case following warning is relevant:
Do not build messages by
concatenating text chunks. Such messages can not be properly
translated.
as you are concatenating every string with "".
remove this concatenation as the arguments you are passing are already text. Also, you can use .toString() if at all required anywhere else instead of concatenating your string with ""
I fixed it by using String.format
befor :
textViewAddress.setText("Address"+address+"\n"+"nCountry"+"\n"+"City"+"city"+"\n"+"State"+"state")
after :
textViewAddress.setText(
String.format("Address:%s\nCountry:%s\nCity:%s\nState:%s", address, country, city, state));
You can use this , it works for me
title.setText(MessageFormat.format("{0} {1}", itemList.get(position).getOppName(), itemList.get(position).getBatchNum()));
If you don't need to support i18n, you can disable this lint check in Android Studio
File -> Settings -> Editor -> Inspections -> Android -> Lint -> TextView Internationalization(uncheck this)
prodNameView.setText("" + name); //this produce lint error
val nameStr="" + name;//workaround for quick warning fix require rebuild
prodNameView.setText(nameStr);
I know I am super late for answering this but I think you can store the data in a varible first then you can provide the variable name. eg:-
// Java syntax
String a = ("" + name);
String b = "" + String.format(getString(R.string.string_product_rate_with_ruppe_sign);
String c = "" + new BigDecimal(price).setScale(2, RoundingMode.UP));
prodNameView.setText(a);
prodOriginalPriceView.setText(b, c);
if it is textView you can use like that : myTextView.text = ("Hello World")
in editText you can use myTextView.setText("Hello World")
I am trying to concatenate two strings like the below Method.I Referred from dynamic String using String.xml?
String incorrect = getResources().getString(R.string.username_or_password_incorrect);
mErrorMsgId = String.format(getResources().getString(R.string.username_or_password_incorrectfull), incorrect);
it returns
error: incompatible types required: int found: String
EDIT
I need to replace the %1$s in the below string with this string R.string.username_or_password_incorrect
'<string name="username_or_password_incorrectfull">The username or password you entered is incorrect \- If you\'re a self hosted WordPress.org user, don\'t forget to tap %1$s and fill the URL field</string>'
How to solve this ?
I'm not sure it's possible. If it is, I'm not aware of it.
What you could do, is something like this;
Create 2 string, one that contains The username or password you entered is incorrect \- If you\'re a self hosted WordPress.org user, don\'t forget to tap and another one with and fill the URL field
and then contcatenate it with the 'incorrect' variable.
String a = getResources().getString(R.string.username_or_password_incorrectfull);
String b = getResources().getString(R.string.username_or_password_incorrectfull2);
String mErrorMsgId = a + incorrect + b;
Note: A better approch would be to use the StringBuilder class to concatenate different variables types, but for the sake of example, this should do.
This is very confusing, why would have mErrorMsgId as an int? change this to a String and it won't error anymore:
so change
private int mErrorMsgId;
to
private String mErrorMsgId;
I'm writing a program that generates star wars names. The user inputs their first, last, mother's maiden name, birth city, and first car and the program gives a star wars name. I need the last two characters* of the user inputted last name. I know I can use substring, but I cannot get anything to work. The best I have is:
lastname.substring(lastname.length() -2)
which gives the first two letters of the last name, and not the last. Also, I cannot use lastname.substr(-2) because substr for some reason won't work (not sure why, this would be much easier).
Thanks for any help.
*EDIT: I hope I didn't confuse anyone, I need the last two characters of the last name.
Actually I see my problem now: my original last name variable is
String lastname = console.nextLine().substring(0,2).trim().toUpperCase();
which keeps the first two letters, so the reason I was getting the first two letters was because of this. I understand now. Is there a way to get the last two letters from this same variable?
So if the name was Michael, you just want Micha?
Try:
String trimmedLastName = lastName.substring(0, lastName.length() - 2);
For example:
String lastName = "Michael";
String trimmedLastName = lastName.substring(0, lastName.length() - 2);
System.out.println(trimmedLastName); // prints Micha
The reason mine works and yours doesn't is because the first parameter of substring is where to start. So I start from the first letter, and end on the second last letter (not inclusive).
What yours does is start on the second last letter, and continue on until the end of the string.
However, if you wanted just el from Michael, you could do this:
String lastName = "Michael";
String trimmedLastName = lastName.substring(lastName.length() - 2);
System.out.println(trimmedLastName); // prints el
Try this out,
lastname.substring(lastname.length() -3,lastname.length() -1);
If you need the different ways, here:
StringBuffer myString = new StringBuffer(inputString);
myString.revert();
StringBuffer userInput = new StringBuffer(myString.subString(2));
String result = userInput.revert();
Have a nice day.
Because String is immutable so when you call subString it doesn't change the value of lastname.
I think you should do:
String genName = lastname.subString(lastname.lengh()-2);
lastname.substring(lastname.length() - 2) should return the last 2 letters.
lastname.substring(0, 2) returns the first two.
substring(index) is includive
substring(index1, index2) is inclusive, exclusive respectively.
I have a following data from a file and I would like to see if I can do a regex parsing here
Name (First Name) City Zip
John (retired) 10007
Mark Baltimore 21268
....
....
Avg Salary
70000 100%
Its not a big file and the entire data from the file is available in a String object with a new line characters (\n) (String data = "data from the file")
I am trying to get name, city, zip and then the salary, percentage details
data inside () considered part of Name field.
For Name field space is considered valid and there are no space for other fields.
'Avg Salary' is available only at the end of the file
Will it be easy to do this via regex parsing in Java?
If the text file is space-aligned, you can (and probably should) extract the fields based on the number of characters. So, you take the first n characters in each line as first name, the next m characters as City, and so on.
This is one code to extract using the above method, by calculating the field length of the fields automatically, assuming we know the header.
String data = "data from the file";
// This is just to ensure we have enough space in the array
int numNewLines = data.length()-data.replace("\n","").length();
String[][] result = new String[numNewLines][3];
String[] lines = data.split("\n");
int avgSalary = 0;
int secondFieldStart = lines[0].indexOf("City");
int thirdFieldStart = lines[0].indexOf("Zip");
for(int i=1; i<lines.length; i++){
String line = lines[i].trim();
if(line.equals("Avg Salary")){
avgSalary = Integer.parseInt(lines[i+1].substring(0,secondFieldStart).trim());
break;
}
result[i-1][0] = line.substring(0,secondFieldStart).trim(); // First Name
result[i-1][1] = line.substring(secondFieldStart,thirdFieldStart).trim(); // City
result[i-1][2] = line.substring(thirdFieldStart).trim(); // Zip
}
Using regex will be possible, but it will be more complicated. And regex won't be able to differentiate person's name and city's name anyway:
Consider this case:
John Long-name Joe New York 21003
How would you know the name is John Long-name Joe instead of John Long-name Joe New if you don't know that the length of the first field is at most 20 characters? (note that length of John Long-name Joe is 19 characters, leaving one space between it and New in New York)
Of course if your fields are separated by other characters (like tab character \t), you can split each line based on that. And it's easy to modify the code above to accommodate that =)
Since the solution I proposed above is simpler, I guess you might want to try it instead =)
I have a strange scenario. Query string has value first=second=12123423423423432323234
String queryString = request.getParameter("first=second=12123423423423432323234")
So i have to:
capture 'first' and 'second' values
validate the query string has 'first' and 'second'.
Could someone please share how I can achieve this in the best possible way?
I really appreciate your help on this.
I believe your query string should look like
first=firstvalue&second=secondvalue
You can use this in your servlet to print the query string
String firstValue = request.getParameter("first");
String secondValue = request.getParameter("second");
System.out.println("Query String:first="+firstValue+"second=+"secondValue);
In your case, where the query string is
first=second=12123423423423432323234
You could do this
String first = request.getParameter("first");
String second = request.getParameter("second");
if(first.contains("second=")){
second = first.split("second=")[1];
first = first.split("second=")[0];
}
out.println("[First:"+first+"][Second:"+second+"]");
If your parameters are separated properly by & (i.e. first=&second=something), then simply .getParameter("first") and .getParameter("second")
Otherwise, you'd need to play with the string - probably split around =, and for the value of first cut until second is encountered. Though I fail to see how will that work if first has a value: first=foosecond=bar?