Reputation: 15789
Imagine I have several Stings containing large ammount of data. I must pass the concatenation of them to a method in a library I use. I can use either a String or a Reader for that.
ps: I already set the initial capacity of the StringBuilder for my first option, but this is no enough, so I am looking for a way to implement 2.
Upvotes: 1
Views: 335
Reputation: 367
You could implement your own version of a reader which uses a base of arrays of strings and then loops through as the read method is called.
You should be able to subclass the Reader class, implementing your own versions of the read(char, int, int) and close() methods. The read(..) method could probably look something like the code below.
import java.io.IOException;
import java.util.Collection;
import java.io.*;
public class StringArrayReader extends Reader {
private String[] strings;
private int iString = 0, iCharInCurrentString = 0;
public StringArrayReader(String[]strings) {
this.strings = strings;
}
public StringArrayReader(Collection<String> strings) {
this(strings.toArray(new String[strings.size()]));
}
@Override
public int read(char[] buf, int off, int len) {
int iCurrentChar=0;
while (iCurrentChar < len) {
if (iCharInCurrentString < strings[iString].length()) {
buf[iCurrentChar+off] = strings[iString].charAt(iCharInCurrentString);
} else if (iString + 1 < strings.length) {
iString++;
iCharInCurrentString = 0;
buf[iCurrentChar+off] = strings[iString].charAt(iCharInCurrentString);
} else { // current string is over and no more strings
break;
}
iCurrentChar++;
iCharInCurrentString++;
}
return iCurrentChar>0? iCurrentChar: -1;
}
@Override
public void close() throws IOException {
}
/* Demo */
public static void main(String[] args) throws IOException {
String s1 = "abcd";
String s2 = "efgh";
Reader r1 = new StringArrayReader(new String[]{s1,s2});
int data = r1.read();
while(data != -1){
char dataChar = (char) data;
System.out.println(dataChar);
data = r1.read();
}
}
}
Upvotes: 1
Reputation: 15729
I don't know of a built-in way or a 3rd party option, but it shouldn't be that hard to write your own Reader, taking a List (or array) of Strings. According to the Reader javadocs:
"The only methods that a subclass must implement are read(char[], int, int) and close()"
And close() should be easy. So you really only need to implement one method, read(char[], int, int). Keep indices of which String you are reading, and where you are in the String. The rest is left as an exercise for the Reader. :-) And you might want to implement read() for speed.
Upvotes: 2
Reputation: 86489
You could implement a custom Reader whose data is drawn from a list of your Strings. Your concrete subclass would be required to implement only two methods: read(char[], int, int)
and close()
. When your reader finishes consuming one String, move on to the next.
Upvotes: 1
Reputation: 2406
You could create an array of Strings and pass that. This will take up much less memory than copying all the Strings into one superstring.
You can also increase the amount of memory used by the JVM with the -Xmx option (e.g. -Xmx2g to allow up to 2 Gb of memory).
Upvotes: 0