3

I want to convert ArrayList of Character to String. I read similar thread like Best way to convert an ArrayList to a string but I want simpler way.

I tried this

List<Character> chars = new ArrayList<Character>();
...
Character[] charArray = (Character[]) chars.toArray();
String output = new String(charArray); // error

But it didn't work because the new String() constructor takes only char[] as parameter. I couldn't convert chars or charArray to char[] type easily.

Aren't there any simple way? Or, do I have to iterate to make a String?

Community
  • 1
  • 1
Sanghyun Lee
  • 21,644
  • 19
  • 100
  • 126
  • 1
    Why don't you use the method with the for loop that iterates on you ArrayList and appends each characters to a String? Not simple enough? – talnicolas Jan 12 '12 at 16:41

5 Answers5

4

This is about as simple as it gets:

StringBuilder result = new StringBuilder(chars.size());
for (Character c : chars) {
  result.append(c);
}
String output = result.toString();
Sean Owen
  • 66,182
  • 23
  • 141
  • 173
  • 3
    Might want to add the list's length as the initial capacity in StringBulder's constructor. That way it won't need to internally grow an array. For the same reason adarshr's approach below might be faster. If speed is a concern I would benchmark both approaches. – lessthanoptimal Jan 12 '12 at 16:56
3

I just ran some benchmarks as I was interested in what the fastest way would be. I ran 4 different methods, each 1.000.000 ( 1 million ) times for good measure.

Side note:

  • The ArrayList was filled with 2710 Characters,
  • the input was some random JSON string i had lying around,
  • my computer is not the strongest ( Cpu: AMD Phenom II X4 955 @3.20 GHz ).
  1. Convert into Array, then into String ( adarshr's Answer )

char[] cs = new char[chars.size()];
for(int x = 0; x < cs.length; x++){
    cs[x] = chars.get(x);
}
String output = new String(cs);

Time: 7716056685 Nanoseconds or ~7.7 Seconds / Index: 1


  1. Use a StringBuilder with predefined size to collect each Character ( Sean Owen's Answer )

StringBuilder result = new StringBuilder(chars.size());
for(Character c : chars){
    result.append(c);
}
String output = result.toString();

Time: 77324811970 Nanoseconds or ~77.3 Seconds / Index: ~10


  1. Use a StringBuilder without predefined size to collect each Character

StringBuilder result = new StringBuilder();
for(Character c : chars){
    result.append(c);
}
String output = result.toString();

Time: 87704351396 Nanoseconds or ~87.7 Seconds / Index: ~11,34


  1. Create an empty String and just += each Character ( Jonathan Grandi's Answer )

String output = "";
for(int x = 0; x < cs.length; x++){
    output += chars.get(x);
}

Time: 4387283410400 Nanoseconds or ~4387.3 Seconds / Index: ~568,59

I actually had to scale this one down. This method was only run 10000 times, which already took ~43 Seconds, I just multiplied the result with 100 to get an approximation of 1.000.000 runs

Conclusion:

Use the "Convert into Array, then into String" method... it's fast... On the other hand, I wouldn't have thought the += operation to be so slow...

How I tested:

final String jsonExample = new String("/* Random Json String here */");
final char[] charsARRAY = jsonExample.toCharArray();
final ArrayList<Character> chars = new ArrayList<Character>();
for(int i = 0; i < charsARRAY.length; i++){
    chars.add(charsARRAY[i]);
}
final long time1, time2;
final int amount = 1000000;

time1 = System.nanoTime();

for(int i = 0; i < amount; i++){
    // Test method here
}

time2 = System.nanoTime();
MLavoie
  • 9,671
  • 41
  • 36
  • 56
Chronove
  • 71
  • 5
3

Yes, unfortunately, you'll have to iterate.

char[] cs = new char[chars.size()];

for(int i = 0; i < cs.length; i++) {
    cs[i] = chars.get(i);
}

String output = new String(cs);
adarshr
  • 61,315
  • 23
  • 138
  • 167
2

A simple way is to append each character to a string:

String myString = "";
for (Character c : charList) {
    myString += c;
}

This iterates through the list to append each character.

Result:

Output of charList is: [a, b, c]. Output of myString is: abc.

  • 1
    This will create a new String object every time it iterates through the loop. Then it will have to garbage-collect them. So if you care about performance, don't use this answer. – David Knipe Jun 03 '17 at 21:35
  • @David Knipe: Good point - thanks! This answer measures "simpler way" using: 1.) Number of characters in solution and 2.) Number of objects seen by the programmer. For performance, Sean Owen's response is a good fit. – Jonathan Grandi Jun 04 '17 at 22:58
0

Try Guava:

Joiner.on("").join(chars);

or commons-lang:

StringUtils.join(chars, null);
kedzi
  • 89
  • 1
  • 5