views:

85

answers:

4

(java 1.5)

I have a need to build up a String, in pieces. I'm given a set of (sub)strings, each with a start and end point of where they belong in the final string. Was wondering if there were some canonical way of doing this. This isn't homework, and I can use any licensable OSS, such as jakarta commons-lang StringUtils etc.

My company has a solution using a CharBuffer, and I'm content to leave it as is (and add some unit tests, of which there are none (?!)) but the code is fairly hideous and I would like something easier to read.

As I said this isn't homework, and I don't need a complete solution, just some pointers to libraries or java classes that might give me some insight. The String.Format didn't seem QUITE right...

I would have to honor inputs too long and too short, etc. Substrings would be overlaid in the order they appear (in case of overlap).

As an example of input, I might have something like:

String:start:end

FO:0:3 (string shorter than field)

BAR:4:5 (String larger than field)

BLEH:5:9 (String overlays previous field)

I'd want to end up with

FO  BBLEH  
01234567890

(Edit: To all - StringBuilder (and specifically, the "pre-allocate to a known length, then use .replace()" theme) seems to be what I'm thinking of. Thanks to all who suggested it!)

+1  A: 

You can use StringUtils.rightPad(str, size) to add the necessary number of spaces. And you can use the following to strip the unneeded characters:

if (str.length() > size) {
   str = str.substring(size);
}
Bozho
Thanks; I'm a big fan of StringUtils, and others in my company seem to want to reinvent those wheels over, and over, and over, and over... it's so frustrating.
Michael Campbell
+5  A: 
StringBuilder output = new StringBuilder();
// for each input element
{
    while (output.length() < start)
    {
        output.append(' ');
    }
    output.replace(start, end, string);
}

You could also establish the final size of output before inserting any string into it. You could make a first pass through the input elements to find the largest end. This will be the final size of output.

char[] spaces = new char[size];
Arrays.fill(spaces, ' ');
output.append(spaces);
Matthew T. Staebler
+1  A: 

If I understand your requirements correctly, you should be able to do this with the standard java.lang.StringBuilder:

public class StringAssembler
{
    private final StringBuilder builder = new StringBuilder();

    public void addPiece(String input, int start, int end)
    {
        final String actualInput = input.substring(0, end-start+1);
        builder.insert(start, actualInput);
    }

    public String getFullString()
    {
        return builder.toString();
    }
}

In particular, I don't think that the end parameter is strictly necessary, in that all it can do is change the length of the input string, hence the two steps in my addPiece method.

Note that this is not tested, and probably doesn't do the right thing in edge cases, but it should give you something to start from.

Andrzej Doyle
+2  A: 

Will StringBuilder do?

StringBuilder sb = new StringBuilder();
sb.setLength(20);
sb.replace(0, 3, "FO");
sb.replace(4, 5, "BAR");
sb.replace(5, 9, "BLEH");
System.out.println("[" + sb.toString().replace('\0', ' ') + "]");
// prints "[FO  BBLEH            ]"
polygenelubricants