I am trying to concat String array values in a String, The below code does not work
private void newString() {
String str = "Split me";
String[] tokens = str.split("[ ]+");
String newStr = new String();
for(int i=0; i<tokens.length; i++){
newStr.concat(tokens[i]);
}
System.out.println("NEW STRING IS : " + newStr);
}
public static void main(String[] args){
Main m = new Main();
m.newString();
}
When you call newStr.concat(tokens[i]); this doesn't modify newStr, it returns a new String that is the result of the concatenation. You aren't doing anything with the result.
You need to do something like: newStr = newStr.concat(tokens[i]);
String is an immutable type in java, so it's methods work like this, returning a new String object. Consider using a (mutable) StringBuilder instead. StringBuilder maintains an internal buffer that can grow, and so avoids the unnecessary String copies that come with using concatenation and immutable Strings.
String is immutable. Naturally, String.concat returns a brand new String.
... a new String object is created, representing a character sequence that is the concatenation of the character sequence represented by this String object and the character sequence represented by the argument string.
The way you're trying to do it, the code should look like...
String glued = "";
for (final String token : tokens) {
glued = glued.concat(token);
}
Now, the problem I have with this approach is that you're doing a lot of copies of the String data. Each concat copies all of the data in glued as well as the data in token. Now, think about the implications of that... I'm not a fan of premature optimization, but I believe the logical way to achieve this is to instead use a StringBuilder as follows...
final StringBuffer buf = new StringBuffer();
for (final String token : tokens) {
buf.append(token);
}
final String glued = buf.toString();
I try to fix it with StringBuilder,here is the new codes.
private void newString() {
String str = "Split me";
String[] tokens = str.split("[ ]+");
StringBuilder newStr = new StringBuilder();
for(int i=0; i<tokens.length; i++){
newStr.append(tokens[i]);
}
System.out.println("NEW STRING IS : " + newStr);
}
Related
I want the Java code for converting an array of strings into an string.
Java 8+
Use String.join():
String str = String.join(",", arr);
Note that arr can also be any Iterable (such as a list), not just an array.
If you have a Stream, you can use the joining collector:
Stream.of("a", "b", "c")
.collect(Collectors.joining(","))
Legacy (Java 7 and earlier)
StringBuilder builder = new StringBuilder();
for(String s : arr) {
builder.append(s);
}
String str = builder.toString();
Alternatively, if you just want a "debug-style" dump of an array:
String str = Arrays.toString(arr);
Note that if you're really legacy (Java 1.4 and earlier) you'll need to replace StringBuilder there with StringBuffer.
Android
Use TextUtils.join():
String str = TextUtils.join(",", arr);
General notes
You can modify all the above examples depending on what characters, if any, you want in between strings.
DON'T use a string and just append to it with += in a loop like some of the answers show here. This sends the GC through the roof because you're creating and throwing away as many string objects as you have items in your array. For small arrays you might not really notice the difference, but for large ones it can be orders of magnitude slower.
Use Apache commons StringUtils.join(). It takes an array, as a parameter (and also has overloads for Iterable and Iterator parameters) and calls toString() on each element (if it is not null) to get each elements string representation. Each elements string representation is then joined into one string with a separator in between if one is specified:
String joinedString = StringUtils.join(new Object[]{"a", "b", 1}, "-");
System.out.println(joinedString);
Produces:
a-b-1
I like using Google's Guava Joiner for this, e.g.:
Joiner.on(", ").skipNulls().join("Harry", null, "Ron", "Hermione");
would produce the same String as:
new String("Harry, Ron, Hermione");
ETA: Java 8 has similar support now:
String.join(", ", "Harry", "Ron", "Hermione");
Can't see support for skipping null values, but that's easily worked around.
From Java 8, the simplest way I think is:
String[] array = { "cat", "mouse" };
String delimiter = "";
String result = String.join(delimiter, array);
This way you can choose an arbitrary delimiter.
You could do this, given an array a of primitive type:
StringBuffer result = new StringBuffer();
for (int i = 0; i < a.length; i++) {
result.append( a[i] );
//result.append( optional separator );
}
String mynewstring = result.toString();
Try the Arrays.deepToString method.
Returns a string representation of the "deep contents" of the specified
array. If the array contains other arrays as elements, the string
representation contains their contents and so on. This method is
designed for converting multidimensional arrays to strings
Try the Arrays.toString overloaded methods.
Or else, try this below generic implementation:
public static void main(String... args) throws Exception {
String[] array = {"ABC", "XYZ", "PQR"};
System.out.println(new Test().join(array, ", "));
}
public <T> String join(T[] array, String cement) {
StringBuilder builder = new StringBuilder();
if(array == null || array.length == 0) {
return null;
}
for (T t : array) {
builder.append(t).append(cement);
}
builder.delete(builder.length() - cement.length(), builder.length());
return builder.toString();
}
public class ArrayToString
{
public static void main(String[] args)
{
String[] strArray = new String[]{"Java", "PHP", ".NET", "PERL", "C", "COBOL"};
String newString = Arrays.toString(strArray);
newString = newString.substring(1, newString.length()-1);
System.out.println("New New String: " + newString);
}
}
You want code which produce string from arrayList,
Iterate through all elements in list and add it to your String result
you can do this in 2 ways: using String as result or StringBuffer/StringBuilder.
Example:
String result = "";
for (String s : list) {
result += s;
}
...but this isn't good practice because of performance reason. Better is using StringBuffer (threads safe) or StringBuilder which are more appropriate to adding Strings
String[] strings = new String[25000];
for (int i = 0; i < 25000; i++) strings[i] = '1234567';
String result;
result = "";
for (String s : strings) result += s;
//linear +: 5s
result = "";
for (String s : strings) result = result.concat(s);
//linear .concat: 2.5s
result = String.join("", strings);
//Java 8 .join: 3ms
Public String join(String delimiter, String[] s)
{
int ls = s.length;
switch (ls)
{
case 0: return "";
case 1: return s[0];
case 2: return s[0].concat(delimiter).concat(s[1]);
default:
int l1 = ls / 2;
String[] s1 = Arrays.copyOfRange(s, 0, l1);
String[] s2 = Arrays.copyOfRange(s, l1, ls);
return join(delimiter, s1).concat(delimiter).concat(join(delimiter, s2));
}
}
result = join("", strings);
// Divide&Conquer join: 7ms
If you don't have the choise but to use Java 6 or 7 then you should use Divide&Conquer join.
String array[]={"one","two"};
String s="";
for(int i=0;i<array.length;i++)
{
s=s+array[i];
}
System.out.print(s);
Use Apache Commons' StringUtils library's join method.
String[] stringArray = {"a","b","c"};
StringUtils.join(stringArray, ",");
When we use stream we do have more flexibility, like
map --> convert any array object to toString
filter --> remove when it is empty
join --> Adding joining character
//Deduplicate the comma character in the input string
String[] splits = input.split("\\s*,\\s*");
return Arrays.stream(splits).filter(StringUtils::isNotBlank).collect(Collectors.joining(", "));
If you know how much elements the array has, a simple way is doing this:
String appendedString = "" + array[0] + "" + array[1] + "" + array[2] + "" + array[3];
I have the following piece of code
String Roletext=null;
for(String text1:Rolelist1)
{
Roletext+=text1+",";
}
I want to convert a list into a string. And then I display the value. It takes the null as it first value. If it is not initialized, then it will show error. Please help.
Solution for you question:
String Roletext="";
for(String text1:Rolelist1)
{
Roletext +=text1+",";
}
Reason for this is when you do concatenation with null , the string appends the value with "null"
My suggestion:
I suggest you to use StringBuilder instead of String concatenation.
StringBuilder b=new StringBuilder();
for(String text1:Rolelist1)
{
b.append(text1).append(",");
}
String Roletext=b.toString().replaceAll(",$", "");//get rid of last comma
You should initialize your String first
String Roletext="";
int i;
for(i = 0;i < Rolelist1.size() - 1;i++)
{
Roletext+=Rolelist1.get(i)+",";
}
Roletext+=Rolelist1.get(i);
Or for better performance you can use StringBuilder.
StringBuilder sb=new StringBuilder();
sb.append("Your String");
Define it like this:
String Roletext ="";
You have to inititalize the string first.
String Roletext="";
But it is not good practice to use a String object for building a string using a loop. Use StringBuilder instead:
StringBuilder sb = new StringBuilder();
for(String text1 : rolelist1) {
sb.append(text1);
}
roletext = sb.toString();
String Roletext="";
for(String text1:Rolelist1)
{
Roletext+=text1+",";
}
now it will not take any null values,initially the string is empty if String text="".
But if we are initializing it with null then String takes first value as null.
Null means some random value it doesn't means empty.
Do like this
String Roletext=null;
Rolelist1.remove(Collections.singleton(null)); //This line will remove all null from Rolelist1
for(String text1:Rolelist1)
{
Roletext+=text1+",";
}
String Roletext = Arrays.toString(Rolelist1.toArray());
This is a perfect example where using a StringBuilder is recommended:
StringBuilder roleText = new StringBuilder();
for(String text1:Rolelist1) {
if(roleText.length() > 0) {
roleText.append(",");
}
roleText.append(text1);
}
By the way: The if construct on length is the one I always use to prevent any leading or trailing commas, it's the most elegant solution to prevent this imo ;-)
I have a set of strings which want to combine into one String with all sentences separated with coma like (*.csv)
here is how it goes with me:
String dataContainer;
for(String tempString:setInput){
String finalString = "," + tempString + "," ;
}
This doesn't work with me :(
But it should do for Set ex:
Set<String> setInput = new TreeSet();
setInput.add("Dog");
setInput.add("Cat");
setInput.add("Mouse");
to produce the string:
,Dog,,Cat,,Mouse,
It is better to use StringBuilder
StringBuilder sb= new StringBuilder();
for(String tempString:setInput){
sb.append(",").append(tempString).append(",");
}
Or we can use Java 8 Stream
String joined = Stream.of("A", "B", "C").collect(Collectors.joining("delimiter", "prefix", "suffix"));
Or use the StringJoiner class
Directly Use StringJoiner class
Or the StringBuilder class
new StringBuilder().add("A").add("B").toString()
What You are doing is intializing your result string each time.
Actually ,you want to do
String finalString ="";
for(String tempString:setInput){
finalString += "," + tempString + "," ;
}
But the above approach causes multiple String creations.
But I suggest to go for StringBuilder.
StringBuilder finalStringb =new StringBuilder();
for(String tempString:setInput){
finalStringb.append(",").append(tempString).append(",") ;
}
String finalS = finalStringb.toString();
Maybe you are looking only for
String csvString = "," + String.join(",,", string1, string2, string3) +"," ;
Reference
Solution 1: (If you don't need a delimiter)
I would recommend using concat(Object... objects) from org.assertj.core.util.String.
public static String concat(Object... objects) {
return Arrays.isNullOrEmpty(objects) ? null : (String)java.util.Arrays.stream(objects).map(String::valueOf).collect(Collectors.joining());
}
You can use it like this:
concat("string1", "string2", "string3", "string4");
Solution 2 using StringJoiner (Java 8+):
This is from java.util. You even have the option to specify a prefix and suffix.
StringJoiner stringJoiner = new StringJoiner(", ");
stringJoiner.add("string1");
stringJoiner.add("string2");
stringJoiner.add("string3");
assertEquals("string1, string2, string3", stringJoiner.toString());
Solution 3 using Collectors.joining (Java 8+):
This is a functionality from Java 8 Stream API.
List<String> stringList = Arrays.asList("string1", "string2", "string3");
String concatString = stringList.stream().collect(Collectors.joining(", "));
assertEquals("string1, string2, string3", concatString);
Alternatively, if you are using Java 8, you could try something like this:
public static String join(final Set<String> set){
return new StringBuilder(",").append(set.stream().collect(Collectors.joining(",,"))).append(",").toString();
}
public static void main(String args[]){
Set<String> setInput = new TreeSet<>();
setInput.add("Dog");
setInput.add("Cat");
setInput.add("Mouse");
System.out.println(join(setInput));
}
The output is:
,Cat,,Dog,,Mouse,
Although, I'm a little unsure to why you would want 2 commas in between each element and a comma at the start and end. If you just want one comma separating each element (and no comma at the start or end), modify the join(Set<String>) to look like this:
public static String join(final Set<String> set){
return set.stream().collect(Collectors.joining(",")); //change "," to ", " for spacing
}
After doing so, the new output would be:
Cat,Dog,Mouse
org.apache.commons.lang.StringUtils.join() can come in handy
Assuming there are no restrictions in the characters that can be used in the individual Strings, and the Strings may be empty.
Edit:
Seems like the proper way to do this is to use a separator, and to escape occurances of that separator that already exist in any of the individual strings. Below is my attempt to this, which seems to work. Did miss any cases that will break it?:
public static void main(String args[])
{
Vector<String> strings = new Vector<String>();
strings.add("abab;jmma");
strings.add("defgh;,;");
strings.add("d;;efgh;,;");
strings.add("");
strings.add("");
strings.add(";;");
strings.add(";,;");
String string = combine(strings);
strings= separate(string);
System.out.println();
}
static String combine(Vector<String> strings)
{
StringBuilder builder = new StringBuilder();
for(String string : strings)
{
//don't prepend a SEPARATOR to the first string
if(!builder.toString().equals(""))
{
builder.append(";");
}
string = string.replaceAll(";", ",;");
builder.append(string);
}
return builder.toString();
}
static Vector<String> separate(String string)
{
Vector<String> strings = new Vector<String>();
separate(string, strings, 0);
return strings;
}
static void separate(String string, Vector<String> strings, int currIndex)
{
int nextIndex = -1;
int checkIndex = currIndex;
while(nextIndex == -1 && checkIndex < string.length())
{
nextIndex = string.indexOf(';', checkIndex);
//look back to determine if this occurance is escaped
if(string.charAt(nextIndex - 1) == ',')
{
//this ones is escaped, doesn't count
checkIndex = nextIndex + 1;
nextIndex = -1;
}
}
if(nextIndex == -1)
{
//no more remain
String toAdd = string.substring(currIndex, string.length());
toAdd = toAdd.replaceAll(",;", ";");
strings.add(toAdd);
return;
}
else if(currIndex + 1 == nextIndex)
{
//empty string
strings.add("");
separate(string, strings, nextIndex);
}
else
{
//there could be more
String toAdd = string.substring(currIndex, nextIndex);
toAdd = toAdd.replaceAll(",;", ";");
strings.add(toAdd);
separate(string, strings, nextIndex + 1);
}
}
}
Take your Vector of Strings and convert it to a JSON object and store the JSON object.
( http://www.json.org/ and http://www.json.org/java/ )
With your code, you can recover empty strings using the two-argument version of split:
String[] separate(String string)
{
return string.split(SEPARATOR, -1);
}
If you can truly make no assumptions about the string contents, the only way to do this properly is by escaping the separator sequence (which can then be a single character) wherever it occurs in the source string(s). Obviously, if you escape the separator sequence, you need to unescape the result after splitting. (The escape mechanism will likely require additional at least one additional escape/unescape.)
EDIT
Here's an example (XML-inspired) of escaping and unescaping. It assumes that the separator sequence is "\u0000" (a single NULL character).
/** Returns a String guaranteed to have no NULL character. */
String escape(String source) {
return source.replace("&", "&").replace("\u0000", "&null;");
}
/** Reverses the above escaping and returns the result. */
String unescape(String escaped) {
return source.replace("&null;", "\u0000").replace("&", "&");
}
Many other variations are possible. (It is important that the replacements when unescaping are in reverse order from those used for escaping.) Note that you can still use String.split() to separate the components.
You can build a class that stores the individual strings internally and then outputs a concatenated version of the strings when you call toString. Getting the original strings back is trivial as you already have them stored individually.
You can have the same comportement in two lines of code using Google Guava library (Splitter and Joiner classes).
public String combine(Collection<String> strings) {
return Joiner.on("yourUniqueSeparator").join(strings);
}
public Iterable<String> separate(String toSeparate) {
return Splitter.on("yourUniqueSeparator").split(toSeparate);
}
Take a look at opencsv if you want to use delimited text. The api is rather easy to use, and it takes care of dealing with escaping quotes and the like. However, it treats null values as empty strings, so you might get a,,c if your input was { "a", null, "c" }. If that's not acceptable, you could use a recognizable string and convert it back later.
char tokenSeparator = ',';
char quoteChar = '"';
String inputData[] = {"a","b","c"};
StringWriter stringWriter = new StringWriter();
CSVWriter csvWriter = new CSVWriter(stringWriter, tokenSeparator, quoteChar);
csvWriter.writeNext(inputData);
csvWriter.close();
StringReader stringReader = new StringReader(stringWriter.toString());
CSVReader csvReader = new CSVReader(stringReader, tokenSeparator, quoteChar);
String outputData[] = csvReader.readNext();
I have a string which has the below content
String msg = "The variables &CHAG_EF and &CHAG_DNE_DTE can be embedded"
String test1 = "22/10/2010 00:10:12"
String test2 = "25/10/2010 00:01:12"
I need to search the string variable msg for the string "&CHAG_EF" and if it exists replace with the value of test1 and also search the string variable msg for the string "&CHAG_DNE_DTE" and if it exists replace with the value of test2.
How can i replace them?
So simple!
String msg2 = msg.replace("&CHAG_EF", test1).replace("&CHAG_DNE_DTE", test2);
Firstly, Strings can't be modified in Java so you'll need to create new versions with the correct modified values. There are two ways to approach this problem:
Dynamically hard-code all the replacements like other posters have suggested. This isn't scalable with large strings or a large number of replacements; or
You loop through the String looking for potential variables. If they're in your replacement Map then replace them. This is very similar to How to create dynamic Template String.
The code for (2) looks something like this:
public static String replaceAll(String text, Map<String, String> params) {
Pattern p = Pattern.compile("&(\\w+)");
Matcher m = p.matcher(text);
boolean result = m.find();
if (result) {
StringBuffer sb = new StringBuffer();
do {
String replacement = params.get(m.group(1));
if (replacement == null) {
replacement = m.group();
}
m.appendReplacement(sb, replacement);
result = m.find();
} while (result);
m.appendTail(sb);
return sb.toString();
}
return text;
}
Strings in Java are immutable, so any of the "manipulation" methods return a new string rather than modifying the existing one. One nice thing about this is that you can chain operations in many cases, like this:
String result = msg.replace("&CHAG_EF", test1)
.replace("&CHAG_DNE_DTE", test2);
msg = msg.replace("&CHAG_EF", test1).replace("&CHAG_DNE_DTE", test2);