Effectively convert ArrayList <String []> to a multi-line string in JAVA
ArrayList<String[]> writtenClasses = new ArrayList<String[]>();
// usually there is functional code here that populates
// ArrayList<String[]> writtenClasses with variably 3000
// String[] objects always of exactly 8 lines each
ArrayList<String> processedClasses = new ArrayList<String>();
for(String[] classLines: writtenClasses)
{
for(String classLine: classLines)
{
processedClasses.add(classLine);
}
}
String result = "";
for(String fileLine: processedClasses)
{
result += fileLine + "\n";
}
My code is above. It works great and gives exactly the result that I want, only slowly. It takes about 10 ms per element of an ArrayList of written lists, and that’s fine until I give it big tasks. I suspect there is something that needs to be done with ArrayLists, which takes so much time, but the time and print to console job statistics after each run showed little.
This code above is an adaptation of earlier code in the hope of improving efficiency. This is about 4%. The following code is the old method I used, which takes a little longer than the above.
for(String[] classLines: writtenClasses)
{
for(String classLine: classLines)
{
result += classLine + "\n";
}
writtenClasses.set(writtenClasses.indexOf(classLines), null);
}
writtenClasses.set(writtenClasses.indexOf(classLines), null); , , .
, StackOverflow, , , - , , , .:)
processedClasses. , StringBuilder :
// Consider a large initial size to even avoid reallocation, here I used 64 KB
StringBuilder sb = new StringBuilder(65536);
for (String[] classLines : writtenClasses)
for (String lines : classLines)
sb.append(lines).append('\n');
// Note: you might not even need to convert it to String, read reasoning below
String result = sb.toString();
StringBuilder, CharSequence. CharSequence, String s. FileWriter. StringBuilder String, StringBuilder , String, , .
, , ArrayList, + String s. String java, , , , .
A faster way to do this is to use StringBuilderone that (optionally) forcibly copies the data for each operation:
StringBuilder result = new StringBuilder();
for(String[] classLines: writtenClasses)
{
for(String classLine: classLines)
{
result.append(classLine).append('\n');
}
}
The problem was noted by other answers. With Java 8, an alternative to two nested loops and StringBuilder is to use a thread and a connection collector *:
String result = writtenClasses.stream()
.flatMap(array -> Arrays.stream(array))
.collect(joining("\n"));
* requires import static java.util.Collectors.joining;
based on this question
ewall:
At what point do you switch to StringBuilder? When it effects memory or performance. Or when it might. If you're really only doing this for a couple strings once, no worries. But if you're going to be doing it over and over again, you should see a measurable difference when using StringBuilder.
StringBuilder myString = new StringBuilder();
for(String classLine: classLines)
{
myString.append(classLine).append("\n");
}
StringBuilder somehow improve your performance.