Java: Printing LinkedList without square brackets? - java

This is a fairly simple question. When you print out a LinkedList, like so:
System.out.println(list);
It prints it out, surrounding the list in square brackets like this:
[thing 1, thing 2, thing 3]
Is there a way I can print it out without the square brackets?

Yes - iterate the list and print it (with comma after each, but the last element). However, there are utils to help:
Guava:
String result = Joiner.on(", ").join(list);
commons-lang:
String result = StringUtils.join(list, ", ");
And one note: don't rely on the .toString() method of any object. It is not meant for displaying the object to users, or to be used as a predefined format - it is meant mainly for debugging purposes.

A quick-and-dirty answer is:
String s = list.toString();
System.out.println(s.substring(1, s.length()-1));

You could subclass LinkedList and override it's toString() method, but that seems a little excessive. Instead, iterate over it's elements and construct a String with either a StringBuilder, or a StringBuffer(if concurrency is an issue).
Note:
I suggest you don't follow the answer provided by #Sean Owen, since that's implementation-dependent and therefore, fragile.

This is the default implementation of the toString() on LinkedList. You could extend LinkedList to provide your own implementation or use composition and just implement the java.util.List interface.
public class MyLinkedList<E> implements List<E>
{
private final List<E> delegate;
public MyLinkedList(List<E> list)
{
delegate = list;
}
/**
* #return see overriden class or implemented interface
* #see java.lang.Object#toString()
*/
#Override
public String toString()
{
return "My special toString() method";
}
// implement rest of the java.util.List interface

Modified from AbstractCollection.java:
/*
* #return a string representation of a collection
*/
public static final String collectionToString(Collection c) {
Iterator<E> it = c.iterator();
if (! it.hasNext())
return "";
StringBuilder sb = new StringBuilder();
for (;;) {
E e = it.next();
sb.append(e == c ? "(this Collection)" : e);
if (! it.hasNext())
return sb.toString();
sb.append(',').append(' ');
}
}

StrBuilder builder = new StrBuilder(); // apache commons lang.
for (Object object : yourList)
{
builder.appendSeperator(", ");
builder.append(object.toString());
}
System.out.println(builder.toString());

You can grab the String returned by the .toString() method and remove the first and last character, or make your own list class and override the .toString() method to iterate through the list and print the elements without the brackets. Or you can do it as an anonymous class like:
List<String> list = new List<String>() {
public String toString() {
// Custom To String Stuff Here
}
};
And of course I'm too slow.

If you're into groovy, there's no need to import anything, just do:
list = ["thing 1", "thing 2", "thing 3"]
println list.collect { i -> "$i" }.join(', ')
thing 1, thing 2, thing 3
Same goes with Map collection:
map = [I:"James Bond", love:"rock N roll", id:"007"]
println map.collect { k,v -> "$k = $v" }.join('\n')
I = James Bond
love = rock N roll
id = 007

Related

Print ArrayList

I have an ArrayList that contains Address objects.
How do I print the values of this ArrayList, meaning I am printing out the contents of the Array, in this case numbers.
I can only get it to print out the actual memory address of the array with this code:
for(int i = 0; i < houseAddress.size(); i++) {
System.out.print(houseAddress.get(i));
}
list.toString() is good enough.
The interface List does not define a contract for toString(), but the AbstractCollection base class provides a useful implementation that ArrayList inherits.
Add toString() method to your address class then do
System.out.println(Arrays.toString(houseAddress));
From what I understand you are trying to print an ArrayList of arrays and one way to display that would be
System.out.println(Arrays.deepToString(list.toArray()));
since you haven't provide a custom implementation for toString() method it calls the default on which is going to print the address in memory for that object
solution
in your Address class override the toString() method like this
public class Address {
int addressNo ;
....
....
...
protected String toString(){
return Integer.toString(addressNo);
}
now when you call
houseAddress.get(i) in the `System.out.print()` method like this
System.out.print( houseAddress.get(i) ) the toString() of the Address object will be called
You can simply give it as:
System.out.println("Address:" +houseAddress);
Your output will look like [address1, address2, address3]
This is because the class ArrayList or its superclass would have a toString() function overridden.
Hope this helps.
assium that you have a numbers list like that
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);
if you print the list
//method 1
// Conventional way of printing arraylist
for (int number : numbers) {
System.out.print(number);
}
//method 2
// Lambda Expression to print arraylist
numbers.forEach((Integer value) -> System.out.print(value));
//method 3
// Lambda Expression to print arraylist
numbers.forEach(value -> System.out.print(value));
//method 4
// Lambda Expression (method reference) to print arraylist
numbers.forEach(System.out::print);
Are you saying that ArrayList is storing addresses of arrays because that is what is returning from the toString call, or because that's actually what you're storing?
If you have an ArrayList of arrays (e.g.
int[] arr = {1, 2, 3};
houseAddress.add(arr);
Then to print the array values you need to call Arrays.deepToString:
for (int i = 0; i < houseAddress.size(); i++) {
System.out.println(Arrays.deepToString(houseAddress.get(i)));
}
public void printList(ArrayList<Address> list){
for(Address elem : list){
System.out.println(elem+" ");
}
}
I am not sure if I understood the notion of addresses (I am assuming houseAddress here), but if you are looking for way a to print the ArrayList, here you go:
System.out.println(houseAddress.toString().replaceAll("\\[\\]", ""));
Since Java 8, you can use forEach() method from Iterable interface.
It's a default method. As an argument, it takes an object of class, which implements functional interface Consumer. You can implement Consumer locally in three ways:
With annonymous class:
houseAddress.forEach(new Consumer<String>() {
#Override
public void accept(String s) {
System.out.println(s);
}
});
lambda expression:
houseAddress.forEach(s -> System.out.println(s));
or by using method reference:
houseAddress.forEach(System.out::print);
This way of printing works for all implementations of Iterable interface.
All of them, gives you the way of defining how the elements will be printed, whereas toString() enforces printing list in one format.
Simplest way to print an ArrayList is by using toString
List<String> a=new ArrayList<>();
a.add("111");
a.add("112");
a.add("113");
System.out.println(a.toString());
Output
[111, 112, 113]
Put houseAddress.get(i) inside the brackets and call .toString() function: i.e Please see below
for(int i = 0; i < houseAddress.size(); i++) {
System.out.print((houseAddress.get(i)).toString());
}
This helped to me:
System.out.println(Arrays.toString(codeLangArray.toArray()));
public static void main(String[] args) {
List<Moyen> list = new ArrayList<Moyen>();
Moyen m1 = new Moyen();
m1.setCodification("c1");
m1.setCapacityManager("Avinash");
Moyen m2 = new Moyen();
m2.setCodification("c1");
m2.setCapacityManager("Avinash");
Moyen m3 = new Moyen();
m3.setCodification("c1");
m3.setCapacityManager("Avinash");
list.add(m1);
list.add(m2);
list.add(m3);
System.out.println(Arrays.toString(list.toArray()));
}
You can use an Iterator. It is the most simple and least controvercial thing to do over here. Say houseAddress has values of data type String
Iterator<String> iterator = houseAddress.iterator();
while (iterator.hasNext()) {
out.println(iterator.next());
}
Note : You can even use an enhanced for loop for this as mentioned by me in another answer
if you make the #Override public String toString() as comments,
you will have the same results as you did.
But if you implement your toString() method, it will work.
public class PrintingComplexArrayList {
public static void main(String[] args) {
List houseAddress = new ArrayList();
insertAddress(houseAddress);
printMe1(houseAddress);
printMe2(houseAddress);
}
private static void insertAddress(List address)
{
address.add(new Address(1));
address.add(new Address(2));
address.add(new Address(3));
address.add(new Address(4));
}
private static void printMe1(List address)
{
for (int i=0; i<address.size(); i++)
System.out.println(address.get(i));
}
private static void printMe2(List address)
{
System.out.println(address);
}
}
class Address{
private int addr;
public Address(int i)
{
addr = i;
}
#Override public String toString()
{
Integer iAddr = new Integer (addr);
return iAddr.toString();
}
}
You can even use an enhanced for loop or an iterator like:
for (String name : houseAddress) {
System.out.println(name);
}
You can change it to whatever data type houseAddress is and it avoids unnecessary conversions
Make sure you have a getter in House address class and then use:
for(int i = 0; i < houseAddress.size(); i++) {
System.out.print(houseAddress.get(i)**.getAddress()**);
}
you can use print format if you just want to print the element on the console.
for(int i = 0; i < houseAddress.size(); i++) {
System.out.printf("%s", houseAddress.get(i));
}
Assuming that houseAddress.get(i) is an ArrayList you can add toString() after the ArrayList :
for(int i = 0; i < houseAddress.size(); i++) {
System.out.print(houseAddress.get(i).toString());
}
A general example:
ArrayList<Double> a = new ArrayList();
a.add(2.);
a.add(32.);
System.out.println(a.toString());
// output
// [2.0, 32.0]
This is a simple code of add the value in ArrayList and print the ArrayList Value
public class Samim {
public static void main(String args[]) {
// Declare list
List<String> list = new ArrayList<>();
// Add value in list
list.add("First Value ArrayPosition=0");
list.add("Second Value ArrayPosition=1");
list.add("Third Value ArrayPosition=2");
list.add("Fourth Value ArrayPosition=3");
list.add("Fifth Value ArrayPosition=4");
list.add("Sixth Value ArrayPosition=5");
list.add("Seventh Value ArrayPosition=6");
String[] objects1 = list.toArray(new String[0]);
// Print Position Value
System.err.println(objects1[2]);
// Print All Value
for (String val : objects1) {
System.out.println(val);
}
}
}
JSON
An alternative Solution could be converting your list in the JSON format and print the Json-String. The advantage is a well formatted and readable Object-String without a need of implementing the toString(). Additionaly it works for any other Object or Collection on the fly.
Example using Google's Gson:
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
...
public static void printJsonString(Object o) {
GsonBuilder gsonBuilder = new GsonBuilder();
/*
* Some options for GsonBuilder like setting dateformat or pretty printing
*/
Gson gson = gsonBuilder.create();
String json= gson.toJson(o);
System.out.println(json);
}
Add toString() method to your class
houseAddress.forEach(System.out::println);
Consider using an "Enhanced for loop" I had to do this solution for a scenario in which the arrayList was coming from a class object
changing the String datatype to the appropriate datatype or class object as desired.
ArrayList<String> teamRoster = new ArrayList<String>();
// Adding player names
teamRoster.add("Mike");
teamRoster.add("Scottie");
teamRoster.add("Toni");
System.out.println("Current roster: ");
for (String playerName : teamRoster) {
System.out.println(playerName);
// if using an object datatype, you may need to use a solution such as playerName.getPlayer()
}

Remove brackets [] from a list set to a textview?

I am parsing content using the following code with jsoup.
try{
Elements divElements = jsDoc.getElementsByTag("div");
for(Element divElement : divElements){
if(divElement.attr("class").equals("article-content")){
textList.add(divElement.text());
text = textList.toString();
}
}
}
catch(Exception e){
System.out.println("Couldnt get content");
}
The only problem is the content is returned with brackets around it [] like that.
Im guessing it is becaue of the list i am setting it to. How can i remove these?
Replace:
text = textList.toString();
with:
text = textList.toString().replace("[", "").replace("]", "");
Using regex to replace the leading and trailing brackets, String.replace() doesn't work for the edge cases that the list's content contains brackets.
String text = textList.toString().replaceAll("(^\\[|\\]$)", "");
Yes, its because of the List. You have to Options:
Subclass whatever TextList is, and override toString()
or
String temp = textList.toString();
text = temp.subString(1, temp.size() -2);
For most objects, the toString() method is not intended to be used for display, but usually debugging. This is because the toString() method generally doesn't have a specific format and could vary depending on the particular class used. For example, a LinkedList and ArrayList could return different values from toString(). It's unlikely, but its something you should avoid relying on. Of course, if the object represents actual text (String, StringBuilder, CharSequence), the above doesn't apply.
Also, you are creating and assigning the string multiple times in the for loop. Instead, you should only create the string after the for loop is done.
To create the string you can roll your own or use a library like Apache commons lang, which has a StringUtils.join() utility method.
If you roll your own, it might look something like this:
Elements divElements = jsDoc.getElementsByTag("div");
Iterator<Element> iterator = divElements.iterator();
StringBuilder builder = new StringBuilder();
while (iterator.hasNext()){
Element divElement = iterator.next()
if (divElement.attr("class").equals("article-content")){
builder.append(divElement.text());
if (iterator.hasNext()) {
builder.append(", ");
}
}
}
text = builder.toString();
Implement your own method to create the String you need using iteration and StringBuffer. It is not a good practice to replace parentheses or substring such output.
You may override toString() method.
Set example:
class SetPrinter<E> extends HashSet<E> {
public SetPrinter(Set<E> set) {
super(set);
}
#Override
public String toString() {
Iterator<E> i = iterator();
if (!i.hasNext()) {
return "";
}
StringBuilder sb = new StringBuilder();
for (; ; ) {
E e = i.next();
sb.append(e == this ? "(this Collection)" : e);
if (!i.hasNext())
return sb.toString();
sb.append(",");
}
}
}
Use:
new SetPrinter(SetToPrint).toString();
Simply use like this. It is working for me.
Text(text.toString().replaceAll('[', "").replaceAll(']', ''));

How do I determine whether an array contains a particular value in Java?

I have a String[] with values like so:
public static final String[] VALUES = new String[] {"AB","BC","CD","AE"};
Given String s, is there a good way of testing whether VALUES contains s?
Arrays.asList(yourArray).contains(yourValue)
Warning: this doesn't work for arrays of primitives (see the comments).
Since java-8 you can now use Streams.
String[] values = {"AB","BC","CD","AE"};
boolean contains = Arrays.stream(values).anyMatch("s"::equals);
To check whether an array of int, double or long contains a value use IntStream, DoubleStream or LongStream respectively.
Example
int[] a = {1,2,3,4};
boolean contains = IntStream.of(a).anyMatch(x -> x == 4);
Concise update for Java SE 9
Reference arrays are bad. For this case we are after a set. Since Java SE 9 we have Set.of.
private static final Set<String> VALUES = Set.of(
"AB","BC","CD","AE"
);
"Given String s, is there a good way of testing whether VALUES contains s?"
VALUES.contains(s)
O(1).
The right type, immutable, O(1) and concise. Beautiful.*
Original answer details
Just to clear the code up to start with. We have (corrected):
public static final String[] VALUES = new String[] {"AB","BC","CD","AE"};
This is a mutable static which FindBugs will tell you is very naughty. Do not modify statics and do not allow other code to do so also. At an absolute minimum, the field should be private:
private static final String[] VALUES = new String[] {"AB","BC","CD","AE"};
(Note, you can actually drop the new String[]; bit.)
Reference arrays are still bad and we want a set:
private static final Set<String> VALUES = new HashSet<String>(Arrays.asList(
new String[] {"AB","BC","CD","AE"}
));
(Paranoid people, such as myself, may feel more at ease if this was wrapped in Collections.unmodifiableSet - it could then even be made public.)
(*To be a little more on brand, the collections API is predictably still missing immutable collection types and the syntax is still far too verbose, for my tastes.)
You can use ArrayUtils.contains from Apache Commons Lang
public static boolean contains(Object[] array, Object objectToFind)
Note that this method returns false if the passed array is null.
There are also methods available for primitive arrays of all kinds.
Example:
String[] fieldsToInclude = { "id", "name", "location" };
if ( ArrayUtils.contains( fieldsToInclude, "id" ) ) {
// Do some stuff.
}
Just simply implement it by hand:
public static <T> boolean contains(final T[] array, final T v) {
for (final T e : array)
if (e == v || v != null && v.equals(e))
return true;
return false;
}
Improvement:
The v != null condition is constant inside the method. It always evaluates to the same Boolean value during the method call. So if the input array is big, it is more efficient to evaluate this condition only once, and we can use a simplified/faster condition inside the for loop based on the result. The improved contains() method:
public static <T> boolean contains2(final T[] array, final T v) {
if (v == null) {
for (final T e : array)
if (e == null)
return true;
}
else {
for (final T e : array)
if (e == v || v.equals(e))
return true;
}
return false;
}
Four Different Ways to Check If an Array Contains a Value
Using List:
public static boolean useList(String[] arr, String targetValue) {
return Arrays.asList(arr).contains(targetValue);
}
Using Set:
public static boolean useSet(String[] arr, String targetValue) {
Set<String> set = new HashSet<String>(Arrays.asList(arr));
return set.contains(targetValue);
}
Using a simple loop:
public static boolean useLoop(String[] arr, String targetValue) {
for (String s: arr) {
if (s.equals(targetValue))
return true;
}
return false;
}
Using Arrays.binarySearch():
The code below is wrong, it is listed here for completeness. binarySearch() can ONLY be used on sorted arrays. You will find the result is weird below. This is the best option when array is sorted.
public static boolean binarySearch(String[] arr, String targetValue) {
return Arrays.binarySearch(arr, targetValue) >= 0;
}
Quick Example:
String testValue="test";
String newValueNotInList="newValue";
String[] valueArray = { "this", "is", "java" , "test" };
Arrays.asList(valueArray).contains(testValue); // returns true
Arrays.asList(valueArray).contains(newValueNotInList); // returns false
If the array is not sorted, you will have to iterate over everything and make a call to equals on each.
If the array is sorted, you can do a binary search, there's one in the Arrays class.
Generally speaking, if you are going to do a lot of membership checks, you may want to store everything in a Set, not in an array.
For what it's worth I ran a test comparing the 3 suggestions for speed. I generated random integers, converted them to a String and added them to an array. I then searched for the highest possible number/string, which would be a worst case scenario for the asList().contains().
When using a 10K array size the results were:
Sort & Search : 15
Binary Search : 0
asList.contains : 0
When using a 100K array the results were:
Sort & Search : 156
Binary Search : 0
asList.contains : 32
So if the array is created in sorted order the binary search is the fastest, otherwise the asList().contains would be the way to go. If you have many searches, then it may be worthwhile to sort the array so you can use the binary search. It all depends on your application.
I would think those are the results most people would expect. Here is the test code:
import java.util.*;
public class Test {
public static void main(String args[]) {
long start = 0;
int size = 100000;
String[] strings = new String[size];
Random random = new Random();
for (int i = 0; i < size; i++)
strings[i] = "" + random.nextInt(size);
start = System.currentTimeMillis();
Arrays.sort(strings);
System.out.println(Arrays.binarySearch(strings, "" + (size - 1)));
System.out.println("Sort & Search : "
+ (System.currentTimeMillis() - start));
start = System.currentTimeMillis();
System.out.println(Arrays.binarySearch(strings, "" + (size - 1)));
System.out.println("Search : "
+ (System.currentTimeMillis() - start));
start = System.currentTimeMillis();
System.out.println(Arrays.asList(strings).contains("" + (size - 1)));
System.out.println("Contains : "
+ (System.currentTimeMillis() - start));
}
}
Instead of using the quick array initialisation syntax too, you could just initialise it as a List straight away in a similar manner using the Arrays.asList method, e.g.:
public static final List<String> STRINGS = Arrays.asList("firstString", "secondString" ...., "lastString");
Then you can do (like above):
STRINGS.contains("the string you want to find");
With Java 8 you can create a stream and check if any entries in the stream matches "s":
String[] values = {"AB","BC","CD","AE"};
boolean sInArray = Arrays.stream(values).anyMatch("s"::equals);
Or as a generic method:
public static <T> boolean arrayContains(T[] array, T value) {
return Arrays.stream(array).anyMatch(value::equals);
}
You can use the Arrays class to perform a binary search for the value. If your array is not sorted, you will have to use the sort functions in the same class to sort the array, then search through it.
ObStupidAnswer (but I think there's a lesson in here somewhere):
enum Values {
AB, BC, CD, AE
}
try {
Values.valueOf(s);
return true;
} catch (IllegalArgumentException exc) {
return false;
}
Actually, if you use HashSet<String> as Tom Hawtin proposed you don't need to worry about sorting, and your speed is the same as with binary search on a presorted array, probably even faster.
It all depends on how your code is set up, obviously, but from where I stand, the order would be:
On an unsorted array:
HashSet
asList
sort & binary
On a sorted array:
HashSet
Binary
asList
So either way, HashSet for the win.
Developers often do:
Set<String> set = new HashSet<String>(Arrays.asList(arr));
return set.contains(targetValue);
The above code works, but there is no need to convert a list to set first. Converting a list to a set requires extra time. It can as simple as:
Arrays.asList(arr).contains(targetValue);
or
for (String s : arr) {
if (s.equals(targetValue))
return true;
}
return false;
The first one is more readable than the second one.
If you have the google collections library, Tom's answer can be simplified a lot by using ImmutableSet (http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/ImmutableSet.html)
This really removes a lot of clutter from the initialization proposed
private static final Set<String> VALUES = ImmutableSet.of("AB","BC","CD","AE");
In Java 8 use Streams.
List<String> myList =
Arrays.asList("a1", "a2", "b1", "c2", "c1");
myList.stream()
.filter(s -> s.startsWith("c"))
.map(String::toUpperCase)
.sorted()
.forEach(System.out::println);
One possible solution:
import java.util.Arrays;
import java.util.List;
public class ArrayContainsElement {
public static final List<String> VALUES = Arrays.asList("AB", "BC", "CD", "AE");
public static void main(String args[]) {
if (VALUES.contains("AB")) {
System.out.println("Contains");
} else {
System.out.println("Not contains");
}
}
}
Using a simple loop is the most efficient way of doing this.
boolean useLoop(String[] arr, String targetValue) {
for(String s: arr){
if(s.equals(targetValue))
return true;
}
return false;
}
Courtesy to Programcreek
the shortest solution
the array VALUES may contain duplicates
since Java 9
List.of(VALUES).contains(s);
Use the following (the contains() method is ArrayUtils.in() in this code):
ObjectUtils.java
public class ObjectUtils {
/**
* A null safe method to detect if two objects are equal.
* #param object1
* #param object2
* #return true if either both objects are null, or equal, else returns false.
*/
public static boolean equals(Object object1, Object object2) {
return object1 == null ? object2 == null : object1.equals(object2);
}
}
ArrayUtils.java
public class ArrayUtils {
/**
* Find the index of of an object is in given array,
* starting from given inclusive index.
* #param ts Array to be searched in.
* #param t Object to be searched.
* #param start The index from where the search must start.
* #return Index of the given object in the array if it is there, else -1.
*/
public static <T> int indexOf(final T[] ts, final T t, int start) {
for (int i = start; i < ts.length; ++i)
if (ObjectUtils.equals(ts[i], t))
return i;
return -1;
}
/**
* Find the index of of an object is in given array, starting from 0;
* #param ts Array to be searched in.
* #param t Object to be searched.
* #return indexOf(ts, t, 0)
*/
public static <T> int indexOf(final T[] ts, final T t) {
return indexOf(ts, t, 0);
}
/**
* Detect if the given object is in the given array.
* #param ts Array to be searched in.
* #param t Object to be searched.
* #return If indexOf(ts, t) is greater than -1.
*/
public static <T> boolean in(final T[] ts, final T t) {
return indexOf(ts, t) > -1;
}
}
As you can see in the code above, that there are other utility methods ObjectUtils.equals() and ArrayUtils.indexOf(), that were used at other places as well.
For arrays of limited length use the following (as given by camickr). This is slow for repeated checks, especially for longer arrays (linear search).
Arrays.asList(...).contains(...)
For fast performance if you repeatedly check against a larger set of elements
An array is the wrong structure. Use a TreeSet and add each element to it. It sorts elements and has a fast exist() method (binary search).
If the elements implement Comparable & you want the TreeSet sorted accordingly:
ElementClass.compareTo() method must be compatable with ElementClass.equals(): see Triads not showing up to fight? (Java Set missing an item)
TreeSet myElements = new TreeSet();
// Do this for each element (implementing *Comparable*)
myElements.add(nextElement);
// *Alternatively*, if an array is forceably provided from other code:
myElements.addAll(Arrays.asList(myArray));
Otherwise, use your own Comparator:
class MyComparator implements Comparator<ElementClass> {
int compareTo(ElementClass element1; ElementClass element2) {
// Your comparison of elements
// Should be consistent with object equality
}
boolean equals(Object otherComparator) {
// Your equality of comparators
}
}
// construct TreeSet with the comparator
TreeSet myElements = new TreeSet(new MyComparator());
// Do this for each element (implementing *Comparable*)
myElements.add(nextElement);
The payoff: check existence of some element:
// Fast binary search through sorted elements (performance ~ log(size)):
boolean containsElement = myElements.exists(someElement);
If you don't want it to be case sensitive
Arrays.stream(VALUES).anyMatch(s::equalsIgnoreCase);
Try this:
ArrayList<Integer> arrlist = new ArrayList<Integer>(8);
// use add() method to add elements in the list
arrlist.add(20);
arrlist.add(25);
arrlist.add(10);
arrlist.add(15);
boolean retval = arrlist.contains(10);
if (retval == true) {
System.out.println("10 is contained in the list");
}
else {
System.out.println("10 is not contained in the list");
}
Check this
String[] VALUES = new String[]{"AB", "BC", "CD", "AE"};
String s;
for (int i = 0; i < VALUES.length; i++) {
if (VALUES[i].equals(s)) {
// do your stuff
} else {
//do your stuff
}
}
Arrays.asList() -> then calling the contains() method will always work, but a search algorithm is much better since you don't need to create a lightweight list wrapper around the array, which is what Arrays.asList() does.
public boolean findString(String[] strings, String desired){
for (String str : strings){
if (desired.equals(str)) {
return true;
}
}
return false; //if we get here… there is no desired String, return false.
}
Use below -
String[] values = {"AB","BC","CD","AE"};
String s = "A";
boolean contains = Arrays.stream(values).anyMatch(v -> v.contains(s));
Use Array.BinarySearch(array,obj) for finding the given object in array or not.
Example:
if (Array.BinarySearch(str, i) > -1)` → true --exists
false --not exists
Try using Java 8 predicate test method
Here is a full example of it.
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
public class Test {
public static final List<String> VALUES =
Arrays.asList("AA", "AB", "BC", "CD", "AE");
public static void main(String args[]) {
Predicate<String> containsLetterA = VALUES -> VALUES.contains("AB");
for (String i : VALUES) {
System.out.println(containsLetterA.test(i));
}
}
}
http://mytechnologythought.blogspot.com/2019/10/java-8-predicate-test-method-example.html
https://github.com/VipulGulhane1/java8/blob/master/Test.java
Create a boolean initially set to false. Run a loop to check every value in the array and compare to the value you are checking against. If you ever get a match, set boolean to true and stop the looping. Then assert that the boolean is true.
As I'm dealing with low level Java using primitive types byte and byte[], the best so far I got is from bytes-java https://github.com/patrickfav/bytes-java seems a fine piece of work
You can check it by two methods
A) By converting the array into string and then check the required string by .contains method
String a = Arrays.toString(VALUES);
System.out.println(a.contains("AB"));
System.out.println(a.contains("BC"));
System.out.println(a.contains("CD"));
System.out.println(a.contains("AE"));
B) This is a more efficent method
Scanner s = new Scanner(System.in);
String u = s.next();
boolean d = true;
for (int i = 0; i < VAL.length; i++) {
if (VAL[i].equals(u) == d)
System.out.println(VAL[i] + " " + u + VAL[i].equals(u));
}

The most sophisticated way for creating comma-separated Strings from a Collection/Array/List?

During my work with databases I noticed that I write query strings and in this strings I have to put several restrictions in the where-clause from a list/array/collection. Should look like this:
select * from customer
where customer.id in (34, 26, ..., 2);
You can simplify this by reducing this to the question that you have collection of strings and want to create a comma-separated list of this strings in just one string.
My approach I have used so far is something like that:
String result = "";
boolean first = true;
for(String string : collectionOfStrings) {
if(first) {
result+=string;
first=false;
} else {
result+=","+string;
}
}
But this is as you can see very ugly. You cannot see what happens there on the first look, especially when the constructed strings (like every SQL query) is getting complicated.
What is your (more) elegant way?
Use the Google Guava API's join method:
Joiner.on(",").join(collectionOfStrings);
Note: This answers was good when it was written 11 years ago, but now there are far better options to do this more cleanly in a single line, both using only Java built-in classes or using a utility library. See other answers below.
Since strings are immutable, you may want to use the StringBuilder class if you're going to alter the String in the code.
The StringBuilder class can be seen as a mutable String object which allocates more memory when its content is altered.
The original suggestion in the question can be written even more clearly and efficiently, by taking care of the redundant trailing comma:
StringBuilder result = new StringBuilder();
for(String string : collectionOfStrings) {
result.append(string);
result.append(",");
}
return result.length() > 0 ? result.substring(0, result.length() - 1): "";
I just looked at code that did this today. This is a variation on AviewAnew's answer.
collectionOfStrings = /* source string collection */;
String csList = StringUtils.join(collectionOfStrings.toArray(), ",");
The StringUtils ( <-- commons.lang 2.x, or commons.lang 3.x link) we used is from Apache Commons.
The way I write that loop is:
StringBuilder buff = new StringBuilder();
String sep = "";
for (String str : strs) {
buff.append(sep);
buff.append(str);
sep = ",";
}
return buff.toString();
Don't worry about the performance of sep. An assignment is very fast. Hotspot tends to peel off the first iteration of a loop anyway (as it often has to deal with oddities such as null and mono/bimorphic inlining checks).
If you use it lots (more than once), put it in a shared method.
There is another question on stackoverflow dealing with how to insert a list of ids into an SQL statement.
Since Java 8, you can use:
String String.join(CharSequence delimiter, CharSequence... elements)
String String.join(CharSequence delimiter, Iterable<? extends CharSequence> elements)
If you want to take non-Strings and join them to a String, you can use Collectors.joining(CharSequence delimiter), e.g.:
String joined = anyCollection.stream().map(Object::toString).collect(Collectors.joining(","));
I found the iterator idiom elegant, because it has a test for more elements (ommited null/empty test for brevity):
public static String convert(List<String> list) {
String res = "";
for (Iterator<String> iterator = list.iterator(); iterator.hasNext();) {
res += iterator.next() + (iterator.hasNext() ? "," : "");
}
return res;
}
There's a lot of manual solutions to this, but I wanted to reiterate and update Julie's answer above. Use google collections Joiner class.
Joiner.on(", ").join(34, 26, ..., 2)
It handles var args, iterables and arrays and properly handles separators of more than one char (unlike gimmel's answer). It will also handle null values in your list if you need it to.
String.join(", ", collectionOfStrings)
available in the Java8 api.
alternative to (without the need to add a google guava dependency):
Joiner.on(",").join(collectionOfStrings);
Here's an incredibly generic version that I've built from a combination of the previous suggestions:
public static <T> String buildCommaSeparatedString(Collection<T> values) {
if (values==null || values.isEmpty()) return "";
StringBuilder result = new StringBuilder();
for (T val : values) {
result.append(val);
result.append(",");
}
return result.substring(0, result.length() - 1);
}
You could try
List collections = Arrays.asList(34, 26, "...", 2);
String asString = collection.toString();
// justValues = "34, 26, ..., 2"
String justValues = asString.substring(1, asString.length()-1);
This will be the shortest solution so far, except of using Guava or Apache Commons
String res = "";
for (String i : values) {
res += res.isEmpty() ? i : ","+i;
}
Good with 0,1 and n element list. But you'll need to check for null list.
I use this in GWT, so I'm good without StringBuilder there. And for short lists with just couple of elements its ok too elsewhere ;)
In case someone stumbled over this in more recent times, I have added a simple variation using Java 8 reduce(). It also includes some of the already mentioned solutions by others:
import java.util.Arrays;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import com.google.common.base.Joiner;
public class Dummy {
public static void main(String[] args) {
List<String> strings = Arrays.asList("abc", "de", "fg");
String commaSeparated = strings
.stream()
.reduce((s1, s2) -> {return s1 + "," + s2; })
.get();
System.out.println(commaSeparated);
System.out.println(Joiner.on(',').join(strings));
System.out.println(StringUtils.join(strings, ","));
}
}
In Android you should use this:
TextUtils.join(",",collectionOfStrings.toArray());
I think it's not a good idea contruct the sql concatenating the where clause values like you are doing :
SELECT.... FROM.... WHERE ID IN( value1, value2,....valueN)
Where valueX comes from a list of Strings.
First, if you are comparing Strings they must be quoted, an this it isn't trivial if the Strings could have a quote inside.
Second, if the values comes from the user,or other system, then a SQL injection attack is possible.
It's a lot more verbose but what you should do is create a String like this:
SELECT.... FROM.... WHERE ID IN( ?, ?,....?)
and then bind the variables with Statement.setString(nParameter,parameterValue).
Just another method to deal with this problem. Not the most short, but it is efficient and gets the job done.
/**
* Creates a comma-separated list of values from given collection.
*
* #param <T> Value type.
* #param values Value collection.
* #return Comma-separated String of values.
*/
public <T> String toParameterList(Collection<T> values) {
if (values == null || values.isEmpty()) {
return ""; // Depending on how you want to deal with this case...
}
StringBuilder result = new StringBuilder();
Iterator<T> i = values.iterator();
result.append(i.next().toString());
while (i.hasNext()) {
result.append(",").append(i.next().toString());
}
return result.toString();
}
There are some third-party Java libraries that provide string join method, but you probably don't want to start using a library just for something simple like that. I would just create a helper method like this, which I think is a bit better than your version, It uses StringBuffer, which will be more efficient if you need to join many strings, and it works on a collection of any type.
public static <T> String join(Collection<T> values)
{
StringBuffer ret = new StringBuffer();
for (T value : values)
{
if (ret.length() > 0) ret.append(",");
ret.append(value);
}
return ret.toString();
}
Another suggestion with using Collection.toString() is shorter, but that relies on Collection.toString() returning a string in a very specific format, which I would personally not want to rely on.
If you use Spring, you can do:
StringUtils.arrayToCommaDelimitedString(
collectionOfStrings.toArray()
)
(package org.springframework.util)
List<String> collectionOfStrings = // List of string to concat
String csvStrings = StringUtils.collectionToDelimitedString(collectionOfStrings, ",");
StringUtils from springframeowrk:spring-core
I'm not sure how "sophisticated" this is, but it's certainly a bit shorter. It will work with various different types of collection e.g. Set<Integer>, List<String>, etc.
public static final String toSqlList(Collection<?> values) {
String collectionString = values.toString();
// Convert the square brackets produced by Collection.toString() to round brackets used by SQL
return "(" + collectionString.substring(1, collectionString.length() - 1) + ")";
}
Exercise for reader: modify this method so that it correctly handles a null/empty collection :)
What makes the code ugly is the special-handling for the first case. Most of the lines in this small snippet are devoted, not to doing the code's routine job, but to handling that special case. And that's what alternatives like gimel's solve, by moving the special handling outside the loop. There is one special case (well, you could see both start and end as special cases - but only one of them needs to be treated specially), so handling it inside the loop is unnecessarily complicated.
I've just checked-in a test for my library dollar:
#Test
public void join() {
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
String string = $(list).join(",");
}
it create a fluent wrapper around lists/arrays/strings/etc using only one static import: $.
NB:
using ranges the previous list can be re-writed as $(1, 5).join(",")
The nice thing about the IN expression is that if you have repeated values, it does not change the result. So, just duplicate the first item and process the entire list. This assumes that there is at least one item in the list. If there are no items, I'd suggest checking for that first and then not executing the SQL at all.
This will do the trick, is obvious in what it is doing and does not rely on any external libraries:
StringBuffer inString = new StringBuffer(listOfIDs.get(0).toString());
for (Long currentID : listOfIDs) {
inString.append(",").append(currentID);
}
While I think your best bet is to use Joiner from Guava, if I were to code it by hand I find this approach more elegant that the 'first' flag or chopping the last comma off.
private String commas(Iterable<String> strings) {
StringBuilder buffer = new StringBuilder();
Iterator<String> it = strings.iterator();
if (it.hasNext()) {
buffer.append(it.next());
while (it.hasNext()) {
buffer.append(',');
buffer.append(it.next());
}
}
return buffer.toString();
}
if you have an array you can do:
Arrays.asList(parameters).toString()
Another option, based on what I see here (with slight modifications).
public static String toString(int[] numbers) {
StringBuilder res = new StringBuilder();
for (int number : numbers) {
if (res.length() != 0) {
res.append(',');
}
res.append(number);
}
return res.toString();
}
Join 'methods' are available in Arrays and the classes that extend AbstractCollections but doesn't override toString() method (like virtually all collections in java.util).
For instance:
String s= java.util.Arrays.toString(collectionOfStrings.toArray());
s = s.substing(1, s.length()-1);// [] are guaranteed to be there
That's quite weird way since it works only for numbers alike data SQL wise.
You may be able to use LINQ (to SQL), and you may be able to make use of the Dynamic Query LINQ sample from MS. http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx
java.util.List<String> lista = new java.util.ArrayList<String>();
lista.add("Hola");
lista.add("Julio");
System.out.println(lista.toString().replace('[','(').replace(']',')'));
$~(Hola, Julio)
String commaSeparatedNames = namesList.toString().replaceAll( "[\\[|\\]| ]", "" ); // replace [ or ] or blank
The string representation consists of a list of the collection's
elements in the order they are returned by its iterator, enclosed in
square brackets ("[]"). Adjacent elements are separated by the
characters ", " (comma and space).
AbstractCollection javadoc
List token=new ArrayList(result);
final StringBuilder builder = new StringBuilder();
for (int i =0; i < tokens.size(); i++){
builder.append(tokens.get(i));
if(i != tokens.size()-1){
builder.append(TOKEN_DELIMITER);
}
}
builder.toString();

What's the best way to build a string of delimited items in Java?

While working in a Java app, I recently needed to assemble a comma-delimited list of values to pass to another web service without knowing how many elements there would be in advance. The best I could come up with off the top of my head was something like this:
public String appendWithDelimiter( String original, String addition, String delimiter ) {
if ( original.equals( "" ) ) {
return addition;
} else {
return original + delimiter + addition;
}
}
String parameterString = "";
if ( condition ) parameterString = appendWithDelimiter( parameterString, "elementName", "," );
if ( anotherCondition ) parameterString = appendWithDelimiter( parameterString, "anotherElementName", "," );
I realize this isn't particularly efficient, since there are strings being created all over the place, but I was going for clarity more than optimization.
In Ruby, I can do something like this instead, which feels much more elegant:
parameterArray = [];
parameterArray << "elementName" if condition;
parameterArray << "anotherElementName" if anotherCondition;
parameterString = parameterArray.join(",");
But since Java lacks a join command, I couldn't figure out anything equivalent.
So, what's the best way to do this in Java?
Pre Java 8:
Apache's commons lang is your friend here - it provides a join method very similar to the one you refer to in Ruby:
StringUtils.join(java.lang.Iterable,char)
Java 8:
Java 8 provides joining out of the box via StringJoiner and String.join(). The snippets below show how you can use them:
StringJoiner
StringJoiner joiner = new StringJoiner(",");
joiner.add("01").add("02").add("03");
String joinedString = joiner.toString(); // "01,02,03"
String.join(CharSequence delimiter, CharSequence... elements))
String joinedString = String.join(" - ", "04", "05", "06"); // "04 - 05 - 06"
String.join(CharSequence delimiter, Iterable<? extends CharSequence> elements)
List<String> strings = new LinkedList<>();
strings.add("Java");strings.add("is");
strings.add("cool");
String message = String.join(" ", strings);
//message returned is: "Java is cool"
You could write a little join-style utility method that works on java.util.Lists
public static String join(List<String> list, String delim) {
StringBuilder sb = new StringBuilder();
String loopDelim = "";
for(String s : list) {
sb.append(loopDelim);
sb.append(s);
loopDelim = delim;
}
return sb.toString();
}
Then use it like so:
List<String> list = new ArrayList<String>();
if( condition ) list.add("elementName");
if( anotherCondition ) list.add("anotherElementName");
join(list, ",");
In the case of Android, the StringUtils class from commons isn't available, so for this I used
android.text.TextUtils.join(CharSequence delimiter, Iterable tokens)
http://developer.android.com/reference/android/text/TextUtils.html
The Google's Guava library has com.google.common.base.Joiner class which helps to solve such tasks.
Samples:
"My pets are: " + Joiner.on(", ").join(Arrays.asList("rabbit", "parrot", "dog"));
// returns "My pets are: rabbit, parrot, dog"
Joiner.on(" AND ").join(Arrays.asList("field1=1" , "field2=2", "field3=3"));
// returns "field1=1 AND field2=2 AND field3=3"
Joiner.on(",").skipNulls().join(Arrays.asList("London", "Moscow", null, "New York", null, "Paris"));
// returns "London,Moscow,New York,Paris"
Joiner.on(", ").useForNull("Team held a draw").join(Arrays.asList("FC Barcelona", "FC Bayern", null, null, "Chelsea FC", "AC Milan"));
// returns "FC Barcelona, FC Bayern, Team held a draw, Team held a draw, Chelsea FC, AC Milan"
Here is an article about Guava's string utilities.
In Java 8 you can use String.join():
List<String> list = Arrays.asList("foo", "bar", "baz");
String joined = String.join(" and ", list); // "foo and bar and baz"
Also have a look at this answer for a Stream API example.
in Java 8 you can do this like:
list.stream().map(Object::toString)
.collect(Collectors.joining(delimiter));
if list has nulls you can use:
list.stream().map(String::valueOf)
.collect(Collectors.joining(delimiter))
it also supports prefix and suffix:
list.stream().map(String::valueOf)
.collect(Collectors.joining(delimiter, prefix, suffix));
You can generalize it, but there's no join in Java, as you well say.
This might work better.
public static String join(Iterable<? extends CharSequence> s, String delimiter) {
Iterator<? extends CharSequence> iter = s.iterator();
if (!iter.hasNext()) return "";
StringBuilder buffer = new StringBuilder(iter.next());
while (iter.hasNext()) buffer.append(delimiter).append(iter.next());
return buffer.toString();
}
Use an approach based on java.lang.StringBuilder! ("A mutable sequence of characters. ")
Like you mentioned, all those string concatenations are creating Strings all over. StringBuilder won't do that.
Why StringBuilder instead of StringBuffer? From the StringBuilder javadoc:
Where possible, it is recommended that this class be used in preference to StringBuffer as it will be faster under most implementations.
I would use Google Collections. There is a nice Join facility.
http://google-collections.googlecode.com/svn/trunk/javadoc/index.html?com/google/common/base/Join.html
But if I wanted to write it on my own,
package util;
import java.util.ArrayList;
import java.util.Iterable;
import java.util.Collections;
import java.util.Iterator;
public class Utils {
// accept a collection of objects, since all objects have toString()
public static String join(String delimiter, Iterable<? extends Object> objs) {
if (objs.isEmpty()) {
return "";
}
Iterator<? extends Object> iter = objs.iterator();
StringBuilder buffer = new StringBuilder();
buffer.append(iter.next());
while (iter.hasNext()) {
buffer.append(delimiter).append(iter.next());
}
return buffer.toString();
}
// for convenience
public static String join(String delimiter, Object... objs) {
ArrayList<Object> list = new ArrayList<Object>();
Collections.addAll(list, objs);
return join(delimiter, list);
}
}
I think it works better with an object collection, since now you don't have to convert your objects to strings before you join them.
Apache commons StringUtils class has a join method.
Java 8
stringCollection.stream().collect(Collectors.joining(", "));
Java 8 Native Type
List<Integer> example;
example.add(1);
example.add(2);
example.add(3);
...
example.stream().collect(Collectors.joining(","));
Java 8 Custom Object:
List<Person> person;
...
person.stream().map(Person::getAge).collect(Collectors.joining(","));
Use StringBuilder and class Separator
StringBuilder buf = new StringBuilder();
Separator sep = new Separator(", ");
for (String each : list) {
buf.append(sep).append(each);
}
Separator wraps a delimiter. The delimiter is returned by Separator's toString method, unless on the first call which returns the empty string!
Source code for class Separator
public class Separator {
private boolean skipFirst;
private final String value;
public Separator() {
this(", ");
}
public Separator(String value) {
this.value = value;
this.skipFirst = true;
}
public void reset() {
skipFirst = true;
}
public String toString() {
String sep = skipFirst ? "" : value;
skipFirst = false;
return sep;
}
}
You can use Java's StringBuilder type for this. There's also StringBuffer, but it contains extra thread safety logic that is often unnecessary.
And a minimal one (if you don't want to include Apache Commons or Gauva into project dependencies just for the sake of joining strings)
/**
*
* #param delim : String that should be kept in between the parts
* #param parts : parts that needs to be joined
* #return a String that's formed by joining the parts
*/
private static final String join(String delim, String... parts) {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < parts.length - 1; i++) {
builder.append(parts[i]).append(delim);
}
if(parts.length > 0){
builder.append(parts[parts.length - 1]);
}
return builder.toString();
}
Why not write your own join() method? It would take as parameters collection of Strings and a delimiter String. Within the method iterate over the collection and build up your result in a StringBuffer.
If you are using Spring MVC then you can try following steps.
import org.springframework.util.StringUtils;
List<String> groupIds = new List<String>;
groupIds.add("a");
groupIds.add("b");
groupIds.add("c");
String csv = StringUtils.arrayToCommaDelimitedString(groupIds.toArray());
It will result to a,b,c
If you're using Eclipse Collections, you can use makeString() or appendString().
makeString() returns a String representation, similar to toString().
It has three forms
makeString(start, separator, end)
makeString(separator) defaults start and end to empty strings
makeString() defaults the separator to ", " (comma and space)
Code example:
MutableList<Integer> list = FastList.newListWith(1, 2, 3);
assertEquals("[1/2/3]", list.makeString("[", "/", "]"));
assertEquals("1/2/3", list.makeString("/"));
assertEquals("1, 2, 3", list.makeString());
assertEquals(list.toString(), list.makeString("[", ", ", "]"));
appendString() is similar to makeString(), but it appends to an Appendable (like StringBuilder) and is void. It has the same three forms, with an additional first argument, the Appendable.
MutableList<Integer> list = FastList.newListWith(1, 2, 3);
Appendable appendable = new StringBuilder();
list.appendString(appendable, "[", "/", "]");
assertEquals("[1/2/3]", appendable.toString());
If you can't convert your collection to an Eclipse Collections type, just adapt it with the relevant adapter.
List<Object> list = ...;
ListAdapter.adapt(list).makeString(",");
Note: I am a committer for Eclipse collections.
You should probably use a StringBuilder with the append method to construct your result, but otherwise this is as good of a solution as Java has to offer.
Why don't you do in Java the same thing you are doing in ruby, that is creating the delimiter separated string only after you've added all the pieces to the array?
ArrayList<String> parms = new ArrayList<String>();
if (someCondition) parms.add("someString");
if (anotherCondition) parms.add("someOtherString");
// ...
String sep = ""; StringBuffer b = new StringBuffer();
for (String p: parms) {
b.append(sep);
b.append(p);
sep = "yourDelimiter";
}
You may want to move that for loop in a separate helper method, and also use StringBuilder instead of StringBuffer...
Edit: fixed the order of appends.
With Java 5 variable args, so you don't have to stuff all your strings into a collection or array explicitly:
import junit.framework.Assert;
import org.junit.Test;
public class StringUtil
{
public static String join(String delim, String... strings)
{
StringBuilder builder = new StringBuilder();
if (strings != null)
{
for (String str : strings)
{
if (builder.length() > 0)
{
builder.append(delim).append(" ");
}
builder.append(str);
}
}
return builder.toString();
}
#Test
public void joinTest()
{
Assert.assertEquals("", StringUtil.join(",", null));
Assert.assertEquals("", StringUtil.join(",", ""));
Assert.assertEquals("", StringUtil.join(",", new String[0]));
Assert.assertEquals("test", StringUtil.join(",", "test"));
Assert.assertEquals("foo, bar", StringUtil.join(",", "foo", "bar"));
Assert.assertEquals("foo, bar, x", StringUtil.join(",", "foo", "bar", "x"));
}
}
For those who are in a Spring context their StringUtils class is useful as well:
There are many useful shortcuts like:
collectionToCommaDelimitedString(Collection coll)
collectionToDelimitedString(Collection coll, String delim)
arrayToDelimitedString(Object[] arr, String delim)
and many others.
This can be helpful if you are not already using Java 8 and you are already in a Spring context.
I prefer it against the Apache Commons (although very good as well) for the Collection support which is easier like this:
// Encoding Set<String> to String delimited
String asString = org.springframework.util.StringUtils.collectionToDelimitedString(codes, ";");
// Decoding String delimited to Set
Set<String> collection = org.springframework.util.StringUtils.commaDelimitedListToSet(asString);
You can try something like this:
StringBuilder sb = new StringBuilder();
if (condition) { sb.append("elementName").append(","); }
if (anotherCondition) { sb.append("anotherElementName").append(","); }
String parameterString = sb.toString();
So basically something like this:
public static String appendWithDelimiter(String original, String addition, String delimiter) {
if (original.equals("")) {
return addition;
} else {
StringBuilder sb = new StringBuilder(original.length() + addition.length() + delimiter.length());
sb.append(original);
sb.append(delimiter);
sb.append(addition);
return sb.toString();
}
}
Don't know if this really is any better, but at least it's using StringBuilder, which may be slightly more efficient.
Down below is a more generic approach if you can build up the list of parameters BEFORE doing any parameter delimiting.
// Answers real question
public String appendWithDelimiters(String delimiter, String original, String addition) {
StringBuilder sb = new StringBuilder(original);
if(sb.length()!=0) {
sb.append(delimiter).append(addition);
} else {
sb.append(addition);
}
return sb.toString();
}
// A more generic case.
// ... means a list of indeterminate length of Strings.
public String appendWithDelimitersGeneric(String delimiter, String... strings) {
StringBuilder sb = new StringBuilder();
for (String string : strings) {
if(sb.length()!=0) {
sb.append(delimiter).append(string);
} else {
sb.append(string);
}
}
return sb.toString();
}
public void testAppendWithDelimiters() {
String string = appendWithDelimitersGeneric(",", "string1", "string2", "string3");
}
Your approach is not too bad, but you should use a StringBuffer instead of using the + sign. The + has the big disadvantage that a new String instance is being created for each single operation. The longer your string gets, the bigger the overhead. So using a StringBuffer should be the fastest way:
public StringBuffer appendWithDelimiter( StringBuffer original, String addition, String delimiter ) {
if ( original == null ) {
StringBuffer buffer = new StringBuffer();
buffer.append(addition);
return buffer;
} else {
buffer.append(delimiter);
buffer.append(addition);
return original;
}
}
After you have finished creating your string simply call toString() on the returned StringBuffer.
Instead of using string concatenation, you should use StringBuilder if your code is not threaded, and StringBuffer if it is.
You're making this a little more complicated than it has to be. Let's start with the end of your example:
String parameterString = "";
if ( condition ) parameterString = appendWithDelimiter( parameterString, "elementName", "," );
if ( anotherCondition ) parameterString = appendWithDelimiter( parameterString, "anotherElementName", "," );
With the small change of using a StringBuilder instead of a String, this becomes:
StringBuilder parameterString = new StringBuilder();
if (condition) parameterString.append("elementName").append(",");
if (anotherCondition) parameterString.append("anotherElementName").append(",");
...
When you're done (I assume you have to check a few other conditions as well), just make sure you remove the tailing comma with a command like this:
if (parameterString.length() > 0)
parameterString.deleteCharAt(parameterString.length() - 1);
And finally, get the string you want with
parameterString.toString();
You could also replace the "," in the second call to append with a generic delimiter string that can be set to anything. If you have a list of things you know you need to append (non-conditionally), you could put this code inside a method that takes a list of strings.
//Note: if you have access to Java5+,
//use StringBuilder in preference to StringBuffer.
//All that has to be replaced is the class name.
//StringBuffer will work in Java 1.4, though.
appendWithDelimiter( StringBuffer buffer, String addition,
String delimiter ) {
if ( buffer.length() == 0) {
buffer.append(addition);
} else {
buffer.append(delimiter);
buffer.append(addition);
}
}
StringBuffer parameterBuffer = new StringBuffer();
if ( condition ) {
appendWithDelimiter(parameterBuffer, "elementName", "," );
}
if ( anotherCondition ) {
appendWithDelimiter(parameterBuffer, "anotherElementName", "," );
}
//Finally, to return a string representation, call toString() when returning.
return parameterBuffer.toString();
So a couple of things you might do to get the feel that it seems like you're looking for:
1) Extend List class - and add the join method to it. The join method would simply do the work of concatenating and adding the delimiter (which could be a param to the join method)
2) It looks like Java 7 is going to be adding extension methods to java - which allows you just to attach a specific method on to a class: so you could write that join method and add it as an extension method to List or even to Collection.
Solution 1 is probably the only realistic one, now, though since Java 7 isn't out yet :) But it should work just fine.
To use both of these, you'd just add all your items to the List or Collection as usual, and then call the new custom method to 'join' them.

Categories