String Builder to String Array in java - java

I am trying to convert String builder to String array in java.I have used to String method to convert the Stringbuilder to String and then use split method to convert it to String array.
I am facing some issue in array size. The output of String builder is as follows: 0,,1,,,,,,,,,,2,,,. Actually it contains 15 elements, but it's showing the size of stringbuilder as 18. And after converting to String array, it's showing size as 13.
Am I doing wrong method? Is there is other method to convert String builder to String Array?
StringBuilder output = new StringBuilder();
for (String str : listToSearch) {
int index = findIndex(headerArrayList, str);
if (index > -1) {
output.append(index);
} else {
output.append(str);
}
output.append(",");
}
String out = output.toString();
String[] destIndexArray = out.split(",");
The findIndex method:
private static int findIndex(List<String> headerList, String element) {
for (int i = 0; i < headerList.size(); i++) {
if (headerList.get(i).equals(element)) {
return i;
}
}
return -1;
}

Am I doing wrong method?
There are many places your code need improvements. I'm suggesting some:
Instead of re-inventing wheel, look for existing API: https://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html#indexOf(java.lang.Object)
You can add only Strings instead of index.
for (String str :listToSearch) {
int index=headerArrayList.indexOf(str);
if (index < 0) {
output.append(str);
output.append(",");
}
// if(!headerArrayList.contains(str))
// output.append(str);
// output.append(",");
}
Use List<String> instead of StringBuilder.
Is there is other method to convert String builder to String Array?
Yes, but if you follow above points, you won't need it. but since you asked. See this: How can a StringBuilder best be converted to a String[]?

See using stringbuilder and again manipulating it and converting it into array is not a good idea. Instead insert everything into list of string, and to check if string is integer or not use this :
str.matches("^-?\\d+$");
And if you want to convert it into array you can do that
String[] str = list.toArray(new String[list.size()])

Have you simply tried in it with one line code:
stringBuilder.toString().split("delimiter"); ?
Which is in your case, might look like:
destIndexArray = output.toString().split(",");
If that doesnt work, then instead of converting into a StringBuilder, you can do this:
List<String> output = new List<String>();
for (String str : listToSearch) {
int index = findIndex(headerArrayList, str);
if (index > -1) {
output.add(index);
} else {
output.add(str);
}
}
I think in this case you can do whatever with your list, no need of delimiter. Hope it helps!

Related

How do I broadcast all arguments in a command? [duplicate]

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];

How to display a converted string from a list without null value?

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 ;-)

Smart way to combine multiple Strings into a single String that can later be separated into the original Strings?

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();

A quick and easy way to join array elements with a separator (the opposite of split) in Java [duplicate]

This question already has answers here:
Java function for arrays like PHP's join()?
(24 answers)
Closed 7 years ago.
See Related .NET question
I'm looking for a quick and easy way to do exactly the opposite of split
so that it will cause ["a","b","c"] to become "a,b,c"
Iterating through an array requires either adding a condition (if this is not the last element, add the seperator) or using substring to remove the last separator.
I'm sure there is a certified, efficient way to do it (Apache Commons?)
How do you prefer doing it in your projects?
Using Java 8 you can do this in a very clean way:
String.join(delimiter, elements);
This works in three ways:
1) directly specifying the elements
String joined1 = String.join(",", "a", "b", "c");
2) using arrays
String[] array = new String[] { "a", "b", "c" };
String joined2 = String.join(",", array);
3) using iterables
List<String> list = Arrays.asList(array);
String joined3 = String.join(",", list);
If you're on Android you can TextUtils.join(delimiter, tokens)
I prefer Guava over Apache StringUtils for this particular problem:
Joiner.on(separator).join(array)
Compared to StringUtils, the Joiner API has a fluent design and is a bit more flexible, e.g. null elements may be skipped or replaced by a placeholder. Also, Joiner has a feature for joining maps with a separator between key and value.
Apache Commons Lang does indeed have a StringUtils.join method which will connect String arrays together with a specified separator.
For example:
String[] s = new String[] {"a", "b", "c"};
String joined = StringUtils.join(s, ","); // "a,b,c"
However, I suspect that, as you mention, there must be some kind of conditional or substring processing in the actual implementation of the above mentioned method.
If I were to perform the String joining and didn't have any other reasons to use Commons Lang, I would probably roll my own to reduce the number of dependencies to external libraries.
A fast and simple solution without any 3rd party includes.
public static String strJoin(String[] aArr, String sSep) {
StringBuilder sbStr = new StringBuilder();
for (int i = 0, il = aArr.length; i < il; i++) {
if (i > 0)
sbStr.append(sSep);
sbStr.append(aArr[i]);
}
return sbStr.toString();
}
"I'm sure there is a certified, efficient way to do it (Apache Commons?)"
yes, apparenty it's
StringUtils.join(array, separator)
http://www.java2s.com/Code/JavaAPI/org.apache.commons.lang/StringUtilsjoinObjectarrayStringseparator.htm
With Java 1.8 there is a new StringJoiner class - so no need for Guava or Apache Commons:
String str = new StringJoiner(",").add("a").add("b").add("c").toString();
Or using a collection directly with the new stream api:
String str = Arrays.asList("a", "b", "c").stream().collect(Collectors.joining(","));
Even easier you can just use Arrays, so you will get a String with the values of the array separated by a ","
String concat = Arrays.toString(myArray);
so you will end up with this: concat = "[a,b,c]"
Update
You can then get rid of the brackets using a sub-string as suggested by Jeff
concat = concat.substring(1, concat.length() -1);
so you end up with concat = "a,b,c"
if you want to use Kotlin:
val concat = myArray.joinToString(separator = ",") //"a,b,c"
You can use replace and replaceAll with regular expressions.
String[] strings = {"a", "b", "c"};
String result = Arrays.asList(strings).toString().replaceAll("(^\\[|\\]$)", "").replace(", ", ",");
Because Arrays.asList().toString() produces: "[a, b, c]", we do a replaceAll to remove the first and last brackets and then (optionally) you can change the ", " sequence for "," (your new separator).
A stripped version (fewer chars):
String[] strings = {"a", "b", "c"};
String result = ("" + Arrays.asList(strings)).replaceAll("(^.|.$)", "").replace(", ", "," );
Regular expressions are very powerful, specially String methods "replaceFirst" and "replaceAll". Give them a try.
All of these other answers include runtime overhead... like using ArrayList.toString().replaceAll(...) which are very wasteful.
I will give you the optimal algorithm with zero overhead;
it doesn't look as pretty as the other options, but internally, this is what they are all doing (after piles of other hidden checks, multiple array allocation and other crud).
Since you already know you are dealing with strings, you can save a bunch of array allocations by performing everything manually. This isn't pretty, but if you trace the actual method calls made by the other implementations, you'll see it has the least runtime overhead possible.
public static String join(String separator, String ... values) {
if (values.length==0)return "";//need at least one element
//all string operations use a new array, so minimize all calls possible
char[] sep = separator.toCharArray();
// determine final size and normalize nulls
int totalSize = (values.length - 1) * sep.length;// separator size
for (int i = 0; i < values.length; i++) {
if (values[i] == null)
values[i] = "";
else
totalSize += values[i].length();
}
//exact size; no bounds checks or resizes
char[] joined = new char[totalSize];
int pos = 0;
//note, we are iterating all the elements except the last one
for (int i = 0, end = values.length-1; i < end; i++) {
System.arraycopy(values[i].toCharArray(), 0,
joined, pos, values[i].length());
pos += values[i].length();
System.arraycopy(sep, 0, joined, pos, sep.length);
pos += sep.length;
}
//now, add the last element;
//this is why we checked values.length == 0 off the hop
System.arraycopy(values[values.length-1].toCharArray(), 0,
joined, pos, values[values.length-1].length());
return new String(joined);
}
it's in StringUtils:
http://www.java2s.com/Code/JavaAPI/org.apache.commons.lang/StringUtilsjoinObjectarrayStringseparator.htm
This options is fast and clear:
public static String join(String separator, String... values) {
StringBuilder sb = new StringBuilder(128);
int end = 0;
for (String s : values) {
if (s != null) {
sb.append(s);
end = sb.length();
sb.append(separator);
}
}
return sb.substring(0, end);
}
This small function always comes in handy.
public static String join(String[] strings, int startIndex, String separator) {
StringBuffer sb = new StringBuffer();
for (int i=startIndex; i < strings.length; i++) {
if (i != startIndex) sb.append(separator);
sb.append(strings[i]);
}
return sb.toString();
}
The approach that I've taken has evolved since Java 1.0 to provide readability and maintain reasonable options for backward-compatibility with older Java versions, while also providing method signatures that are drop-in replacements for those from apache commons-lang. For performance reasons, I can see some possible objections to the use of Arrays.asList but I prefer helper methods that have sensible defaults without duplicating the one method that performs the actual work. This approach provides appropriate entry points to a reliable method that does not require array/list conversions prior to calling.
Possible variations for Java version compatibility include substituting StringBuffer (Java 1.0) for StringBuilder (Java 1.5), switching out the Java 1.5 iterator and removing the generic wildcard (Java 1.5) from the Collection (Java 1.2). If you want to take backward compatibility a step or two further, delete the methods that use Collection and move the logic into the array-based method.
public static String join(String[] values)
{
return join(values, ',');
}
public static String join(String[] values, char delimiter)
{
return join(Arrays.asList(values), String.valueOf(delimiter));
}
// To match Apache commons-lang: StringUtils.join(values, delimiter)
public static String join(String[] values, String delimiter)
{
return join(Arrays.asList(values), delimiter);
}
public static String join(Collection<?> values)
{
return join(values, ',');
}
public static String join(Collection<?> values, char delimiter)
{
return join(values, String.valueOf(delimiter));
}
public static String join(Collection<?> values, String delimiter)
{
if (values == null)
{
return new String();
}
StringBuffer strbuf = new StringBuffer();
boolean first = true;
for (Object value : values)
{
if (!first) { strbuf.append(delimiter); } else { first = false; }
strbuf.append(value.toString());
}
return strbuf.toString();
}
public String join(String[] str, String separator){
String retval = "";
for (String s: str){ retval+= separator + s;}
return retval.replaceFirst(separator, "");
}

Best way to concatenate List of String objects? [duplicate]

This question already has answers here:
Java: convert List<String> to a join()d String
(23 answers)
Closed 6 years ago.
What is the best way to concatenate a list of String objects? I am thinking of doing this way:
List<String> sList = new ArrayList<String>();
// add elements
if (sList != null)
{
String listString = sList.toString();
listString = listString.subString(1, listString.length() - 1);
}
I somehow found this to be neater than using the StringBuilder/StringBuffer approach.
Any thoughts/comments?
Use one of the the StringUtils.join methods in Apache Commons Lang.
import org.apache.commons.lang3.StringUtils;
String result = StringUtils.join(list, ", ");
If you are fortunate enough to be using Java 8, then it's even easier...just use String.join
String result = String.join(", ", list);
Using Java 8+
String str = list.stream().collect(Collectors.joining())
or even
String str = String.join("", list);
Your approach is dependent on Java's ArrayList#toString() implementation.
While the implementation is documented in the Java API and very unlikely to change, there's a chance it could. It's far more reliable to implement this yourself (loops, StringBuilders, recursion whatever you like better).
Sure this approach may seem "neater" or more "too sweet" or "money" but it is, in my opinion, a worse approach.
A variation on codefin's answer
public static String concatStringsWSep(Iterable<String> strings, String separator) {
StringBuilder sb = new StringBuilder();
String sep = "";
for(String s: strings) {
sb.append(sep).append(s);
sep = separator;
}
return sb.toString();
}
If you are developing for Android, there is TextUtils.join provided by the SDK.
This is the most elegant and clean way I've found so far:
list.stream().collect(Collectors.joining(delimiter));
Guava is a pretty neat library from Google:
Joiner joiner = Joiner.on(", ");
joiner.join(sList);
Have you seen this Coding Horror blog entry?
The Sad Tragedy of Micro-Optimization Theater
I am not shure whether or not it is "neater", but from a performance-standpoint it probably won't matter much.
I prefer String.join(list) in Java 8
It seems to me that the StringBuilder will be quick and efficient.
The basic form would look something like this:
public static String concatStrings(List<String> strings)
{
StringBuilder sb = new StringBuilder();
for(String s: strings)
{
sb.append(s);
}
return sb.toString();
}
If that's too simplistic (and it probably is), you can use a similar approach and add a separator like this:
public static String concatStringsWSep(List<String> strings, String separator)
{
StringBuilder sb = new StringBuilder();
for(int i = 0; i < strings.size(); i++)
{
sb.append(strings.get(i));
if(i < strings.size() - 1)
sb.append(separator);
}
return sb.toString();
}
I agree with the others who have responded to this question when they say that you should not rely on the toString() method of Java's ArrayList.
ArrayList inherits its toString()-method from AbstractCollection, ie:
public String toString() {
Iterator<E> i = iterator();
if (! i.hasNext())
return "[]";
StringBuilder sb = new StringBuilder();
sb.append('[');
for (;;) {
E e = i.next();
sb.append(e == this ? "(this Collection)" : e);
if (! i.hasNext())
return sb.append(']').toString();
sb.append(", ");
}
}
Building the string yourself will be far more efficient.
If you really want to aggregate the strings beforehand in some sort of List, you should provide your own method to efficiently join them, e.g. like this:
static String join(Collection<?> items, String sep) {
if(items.size() == 0)
return "";
String[] strings = new String[items.size()];
int length = sep.length() * (items.size() - 1);
int idx = 0;
for(Object item : items) {
String str = item.toString();
strings[idx++] = str;
length += str.length();
}
char[] chars = new char[length];
int pos = 0;
for(String str : strings) {
str.getChars(0, str.length(), chars, pos);
pos += str.length();
if(pos < length) {
sep.getChars(0, sep.length(), chars, pos);
pos += sep.length();
}
}
return new String(chars);
}
I somehow found this to be neater than
using the StringBuilder/StringBuffer
approach.
I guess it depends on what approach you took.
The AbstractCollection#toString() method simply iterates over all the elements and appends them to a StringBuilder. So your method may be saving a few lines of code but at the cost of extra String manipulation. Whether that tradeoff is a good one is up to you.
Rather than depending on ArrayList.toString() implementation, you could write a one-liner, if you are using java 8:
String result = sList.stream()
.reduce("", String::concat);
If you prefer using StringBuffer instead of String since String::concat has a runtime of O(n^2), you could convert every String to StringBuffer first.
StringBuffer result = sList.stream()
.map(StringBuffer::new)
.reduce(new StringBuffer(""), StringBuffer::append);
Next variation on Peter Lawrey's answer without initialization of a new string every loop turn
String concatList(List<String> sList, String separator)
{
Iterator<String> iter = sList.iterator();
StringBuilder sb = new StringBuilder();
while (iter.hasNext())
{
sb.append(iter.next()).append( iter.hasNext() ? separator : "");
}
return sb.toString();
}
Assuming it's faster to just move a pointer / set a byte to null (or however Java implements StringBuilder#setLength), rather than check a condition each time through the loop to see when to append the delimiter, you could use this method:
public static String Intersperse (Collection<?> collection, String delimiter)
{
StringBuilder sb = new StringBuilder ();
for (Object item : collection)
{
if (item == null) continue;
sb.append (item).append (delimiter);
}
sb.setLength (sb.length () - delimiter.length ());
return sb.toString ();
}
In java 8 you can also use a reducer, something like:
public static String join(List<String> strings, String joinStr) {
return strings.stream().reduce("", (prev, cur) -> prev += (cur + joinStr));
}
Depending on the need for performance and amount of elements to be added, this might be an ok solution. If the amount of elements are high, the Arraylists reallocation of memory might be a bit slower than StringBuilder.
Using the Functional Java library, import these:
import static fj.pre.Monoid.stringMonoid;
import static fj.data.List.list;
import fj.data.List;
... then you can do this:
List<String> ss = list("foo", "bar", "baz");
String s = stringMonoid.join(ss, ", ");
Or, the generic way, if you don't have a list of Strings:
public static <A> String showList(List<A> l, Show<A> s) {
return stringMonoid.join(l.map(s.showS_()), ", ");
}
if you have json in your dependencies.you can use new JSONArray(list).toString()

Categories

Resources