HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaMinor

Formatting an ID string

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
formattingstringstackoverflow

Problem

I'm working with an API which gives me 19-digit ID numbers, formatted in blocks of four except for the last 3 digits. While I tried a for loop, I thought it would be most efficient to simply use a StringBuilder and substrings as the length of the ID will never change (documentation is omitted for privacy reasons):

public String getFormattedId() {
    return new StringBuilder()
            .append(id.substring(0, 4))
            .append(" ")
            .append(id.substring(4, 8))
            .append(" ")
            .append(id.substring(8, 12))
            .append(" ")
            .append(id.substring(12, 16))
            .append(" ")
            .append(id.substring(16, 19))
            .toString();
}


This transforms IDs like 1234567890000000123 into the more readable 1234 5678 9000 0000 123, which is also the format used throughout the documentation and website.

I should mention I come from a C# background, and I've heard Java's string + operator is just syntactic sugar for the StringBuilder method like I'm using here.

Solution

It is things like this which drive me nuts, and I agree with you, your solution is good, but ugly. Your solution is also probably close to being as efficient as possible in Java, using the StringBuilder, etc.

There are a couple of things through that you can do to xhange the way you code it. Note that your solution may well be the fastest.... (well, it would be the fastest if you specified a starteing capactity of 23 for the StringBuilder like new StringBuilder(23) ...

How about a for-loop:

private static String formatID(String id) {
    StringBuilder sb = new StringBuilder(25);
    for (int i = 0; i < id.length(); i += 4) {
        sb.append(id.substring(i, Math.min(i + 4, id.length())));
        sb.append(" ");
    }
    sb.setLength(23);
    return sb.toString();
}


The last setLength(23) removes the trailing space on the output.

The actual suggestion I prefer, though, is using a format String, like:

private static String formatFID(String id) {
    return String.format("%s %s %s %s %s", id.substring(0, 4), id.substring(4,  8),
            id.substring(8,  12), id.substring(12,  16), id.substring(16, 19));
}


Finally, for completeness, you can actually use a regex to split the input string at 4-char boundaries. Then, in Java 8, stream the results, and join them with a space:

private static final Pattern FOUR = Pattern.compile("(?<=\\G.{4})");

private static String formatRID(String id) {
    return Stream.of(FOUR.split(id)).collect(Collectors.joining(" "));
}


That's a concise way of doing it.....

Code Snippets

private static String formatID(String id) {
    StringBuilder sb = new StringBuilder(25);
    for (int i = 0; i < id.length(); i += 4) {
        sb.append(id.substring(i, Math.min(i + 4, id.length())));
        sb.append(" ");
    }
    sb.setLength(23);
    return sb.toString();
}
private static String formatFID(String id) {
    return String.format("%s %s %s %s %s", id.substring(0, 4), id.substring(4,  8),
            id.substring(8,  12), id.substring(12,  16), id.substring(16, 19));
}
private static final Pattern FOUR = Pattern.compile("(?<=\\G.{4})");

private static String formatRID(String id) {
    return Stream.of(FOUR.split(id)).collect(Collectors.joining(" "));
}

Context

StackExchange Code Review Q#84071, answer score: 4

Revisions (0)

No revisions yet.