This question already has answers here:
Create formatted string from ArrayList
(7 answers)
Closed 3 years ago.
I have a list of strings that I want to format each of them in the same way. e.g. myListOfStrings = str1, str2, str3, and my format is (%s)
I want to have something like this:
String.format(" (%s) ", myListOfStrings)
Will output
(str1) (str2) (str3)
Is there an elegant way of doing this? or do I have to use a string builder and do a foreach loop on all the strings?
You can do this with Java 8:
import static java.util.stream.Collectors.joining;
public static void main(String[] args) throws Exception {
final List<String> strings = Arrays.asList("a", "b", "c");
final String joined = strings.stream()
.collect(joining(") (", "(", ")"));
System.out.println(joined);
}
Or:
final String joined = strings.stream()
.map(item -> "(" + item + ")")
.collect(joining(" "));
Which one you prefer is a matter of personal preference.
The first joins the items on ) ( which gives:
a) (b) (c
Then you use the prefix and suffix arguments to joining to with prefix with ( and suffix with ), to produce the right outcome.
The second alternative transforms each item to ( + item + ) and then joins them on " ".
The first might also be somewhat faster, as it only requires the creation of one StringBuilder instance - for both the join and the pre/suffix. The second alternative requires the creation of n + 1 StringBuilder instances, one for each element and one for the join on " ".
if you want a one-line solution, you could use one of the the StringUtils.join methods in Apache Commons Lang.
String result = "(" + StringUtils.join(myListOfStrings, ") (") + ")";
You can try this:
List<String> list = new ArrayList<String>();
list.add("str1");
list.add("str2");
list.add("str3");
for(String s : list) {
System.out.print(String.format(" (%s) ", s));
}
String strOut = "";
for(int i=0; i< myListOfStrings.size(); i++){
strOut = strOut +"("+myListOfStrings.get(i)+")";
}
Boris The Spider's answer is what I would go with, but in case you are not using java 8, but maybe you are using Guava you can do something like this, albeit it is a bit verbose:
Joiner.on("").join(Collections2.transform(myListOfStrings, new Function<String, String>() {
#Override
public String apply(String input) {
return String.format(" (%s) ", input);
}
}));
Using Java8 new forEach method for iterating over collections:
public static String format(List<String> list) {
StringBuilder sb = new StringBuilder();
list.forEach(x -> sb.append(String.format(" (%s) ", x)));
return sb.toString();
}
Try it here: https://ideone.com/52EKRH
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 a list like below
List<String> fruits = new ArrayList<>();
fruits.add("apple");
fruits.add("mango");
fruits.add("grapes");
System.out.println(fruits.toString());
I am using lambda expression for printing the list like
fruits.forEach(item->System.out.println(item));
and its working fine my requirement is I need to iterate over the list and concatenate the items to a string
String stringFruits = "";
fruits.forEach(item->stringFruits = stringFruits+item);
this is giving a compile time error saying variable values used in lambda should be effectively final is there any way I can do it in java 8 ?
You need to join via a delimiter. In this case the delimiter is going to be ,; but you can choose any you want.
String result = fruits.stream().collect(Collectors.joining(","));
System.out.println(result);
Java8 introduced a StringJoiner that does what you need (is another alternative to erans comment)
StringJoiner sj = new StringJoiner("-,-");
fruits.forEach(item -> sj.add(item));
here the doc
edit:
for the posterity you can do as well:
String result = fruits.stream().collect(Collectors.joining(","));
System.out.println(result);
or
String stringFruits = String.join(", ", fruits);
System.out.println(stringFruits);
credits and thanks to #Holger
You don’t need to do that by hand at all. If your source is a List, you can just use
String stringFruits = String.join(", ", fruits);
System.out.println(stringFruits);
The first argument to String.join(…) is the delimiter.
Or a pre-Java8 solution:
String combined = "";
for (String s : fruits) {
combined += s;
}
... and one with delimiter:
String combined = "";
for (String s : fruits) {
combined = combined + ", " + s;
}
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
I have a collection of Ingredient objects for which I'd like get all their names (via getName()) and join them into a comma-delimited string. Currently my code looks like this:
public static String getIngredientList(Collection<Ingredient> ingredients) {
final Iterator<Ingredient> iterator = ingredients.iterator();
final String[] names = new String[ingredients.size()];
for (int i = 0; iterator.hasNext(); i++) {
names[i] = iterator.next().getName();
}
return TextUtils.join(", ", names);
}
I'm wondering if there's a more concise way to collect all the names into a String[] object. If this were Ruby, for example, it'd be easy to pull off a short one-liner to do exactly what I need:
ingredients.map(&:name).join(', ')
Using Eclipse Collections you can write the following using JDK 5 - 7:
MutableList<Ingredient> ingredients =
Lists.mutable.with(
new Ingredient("Flour"),
new Ingredient("Sugar"),
new Ingredient("Eggs"),
new Ingredient("Milk"));
MutableList<String> ingredientNames = ingredients.collect(new Function<Ingredient, String>()
{
public String valueOf(Ingredient ingredient)
{
return ingredient.getName();
}
});
String delimitedNames = ingredientNames.makeString(", ");
Assert.assertEquals("Flour, Sugar, Eggs, Milk", delimitedNames);
Using Java 8 with support for lambdas and method references you can compress it down to the following:
MutableList<Ingredient> ingredients =
Lists.mutable.with(
new Ingredient("Flour"),
new Ingredient("Sugar"),
new Ingredient("Eggs"),
new Ingredient("Milk"));
String delimitedNames =
ingredients.collect(Ingredient::getName).makeString(", ");
Assert.assertEquals("Flour, Sugar, Eggs, Milk", delimitedNames);
In this example, using the overloaded form of makeString() without parameters will result in the same string, as makeString() calls makeString(“, “).
String delimitedNames =
ingredients.collect(Ingredient::getName).makeString();
Assert.assertEquals("Flour, Sugar, Eggs, Milk", delimitedNames);
Note: I am a committer for Eclipse Collections.
Why don't you use a StringBuilder in the first place?
The relevant part of the code:
StringBuilder b = new StringBuilder();
for(Ingredient ingredient: ingredients) {
b.append(ingredient.getName() + ", ");
}
return b.toString();
Of course you have to remove the last ", " appended which can be done with using the substring method or not appending the last one.
StringBuilder result = new StringBuilder();
for(String string : collectionOfStrings) {
result.append(string);
result.append(",");
}
return result.length() > 0 ? result.substring(0, result.length() - 1): "";
see the duplicate post:
The most sophisticated way for creating comma-separated Strings from a Collection/Array/List?
I have a few Set<String>s and want to transform each of these into a single String where each element of the original Set is separated by a whitespace " ".
A naive first approach is doing it like this
Set<String> set_1;
Set<String> set_2;
StringBuilder builder = new StringBuilder();
for (String str : set_1) {
builder.append(str).append(" ");
}
this.string_1 = builder.toString();
builder = new StringBuilder();
for (String str : set_2) {
builder.append(str).append(" ");
}
this.string_2 = builder.toString();
Can anyone think of a faster, prettier or more efficient way to do this?
With commons/lang you can do this using StringUtils.join:
String str_1 = StringUtils.join(set_1, " ");
You can't really beat that for brevity.
Update:
Re-reading this answer, I would prefer the other answer regarding Guava's Joiner now. In fact, these days I don't go near apache commons.
Another Update:
Java 8 introduced the method String.join()
String joined = String.join(",", set);
While this isn't as flexible as the Guava version, it's handy when you don't have the Guava library on your classpath.
If you are using Java 8, you can use the native
String.join(CharSequence delimiter, Iterable<? extends CharSequence> elements)
method:
Returns a new String composed of copies of the CharSequence elements joined together with a copy of the specified delimiter.
For example:
Set<String> strings = new LinkedHashSet<>();
strings.add("Java"); strings.add("is");
strings.add("very"); strings.add("cool");
String message = String.join("-", strings);
//message returned is: "Java-is-very-cool"
Set implements Iterable, so simply use:
String.join(" ", set_1);
As a counterpoint to Seanizer's commons-lang answer, if you're using Google's Guava Libraries (which I'd consider the 'successor' to commons-lang, in many ways), you'd use Joiner:
Joiner.on(" ").join(set_1);
with the advantage of a few helper methods to do things like:
Joiner.on(" ").skipNulls().join(set_1);
// If 2nd item was null, would produce "1, 3"
or
Joiner.on(" ").useForNull("<unknown>").join(set_1);
// If 2nd item was null, would produce "1, <unknown>, 3"
It also has support for appending direct to StringBuilders and Writers, and other such niceties.
Maybe a shorter solution:
public String test78 (Set<String> set) {
return set
.stream()
.collect(Collectors.joining(" "));
}
or
public String test77 (Set<String> set) {
return set
.stream()
.reduce("", (a,b)->(a + " " + b));
}
but native, definitely faster
public String test76 (Set<String> set) {
return String.join(" ", set);
}
I don't have the StringUtil library available (I have no choice over that) so using standard Java I came up with this ..
If you're confident that your set data won't include any commas or square brackets, you could use:
mySet.toString().replaceAll("\\[|\\]","").replaceAll(","," ");
A set of "a", "b", "c" converts via .toString() to string "[a,b,c]".
Then replace the extra punctuation as necesary.
Filth.
I use this method:
public static String join(Set<String> set, String sep) {
String result = null;
if(set != null) {
StringBuilder sb = new StringBuilder();
Iterator<String> it = set.iterator();
if(it.hasNext()) {
sb.append(it.next());
}
while(it.hasNext()) {
sb.append(sep).append(it.next());
}
result = sb.toString();
}
return result;
}
I'm confused about the code replication, why not factor it into a function that takes one set and returns one string?
Other than that, I'm not sure that there is much that you can do, except maybe giving the stringbuilder a hint about the expected capacity (if you can calculate it based on set size and reasonable expectation of string length).
There are library functions for this as well, but I doubt they're significantly more efficient.
This can be done by creating a stream out of the set and then combine the elements using a reduce operation as shown below (for more details about Java 8 streams check here):
Optional<String> joinedString = set1.stream().reduce(new
BinaryOperator<String>() {
#Override
public String apply(String t, String u) {
return t + " " + u;
}
});
return joinedString.orElse("");