How do I get the first n characters of a string without checking the size or going out of bounds?

StackOverflow https://stackoverflow.com/questions/1583940

문제

How do I get up to the first n characters of a string in Java without doing a size check first (inline is acceptable) or risking an IndexOutOfBoundsException?

도움이 되었습니까?

해결책

Here's a neat solution:

String upToNCharacters = s.substring(0, Math.min(s.length(), n));

Opinion: while this solution is "neat", I think it is actually less readable than a solution that uses if / else in the obvious way. If the reader hasn't seen this trick, he/she has to think harder to understand the code. IMO, the code's meaning is more obvious in the if / else version. For a cleaner / more readable solution, see @paxdiablo's answer.

다른 팁

Don't reinvent the wheel...:

org.apache.commons.lang.StringUtils.substring(String s, int start, int len)

Javadoc says:

StringUtils.substring(null, *, *)    = null
StringUtils.substring("", * ,  *)    = "";
StringUtils.substring("abc", 0, 2)   = "ab"
StringUtils.substring("abc", 2, 0)   = ""
StringUtils.substring("abc", 2, 4)   = "c"
StringUtils.substring("abc", 4, 6)   = ""
StringUtils.substring("abc", 2, 2)   = ""
StringUtils.substring("abc", -2, -1) = "b"
StringUtils.substring("abc", -4, 2)  = "ab"

Thus:

StringUtils.substring("abc", 0, 4) = "abc"

Apache Commons Lang has a StringUtils.left method for this.

String upToNCharacters = StringUtils.left(s, n);

There's a class of question on SO that sometimes make less than perfect sense, this one is perilously close :-)

Perhaps you could explain your aversion to using one of the two methods you ruled out.

If it's just because you don't want to pepper your code with if statements or exception catching code, one solution is to use a helper function that will take care of it for you, something like:

static String substring_safe (String s, int start, int len) { ... }

which will check lengths beforehand and act accordingly (either return smaller string or pad with spaces).

Then you don't have to worry about it in your code at all, just call:

String s2 = substring_safe (s, 10, 7);

instead of:

String s2 = s.substring (10,7);

This would work in the case that you seem to be worried about (based on your comments to other answers), not breaking the flow of the code when doing lots of string building stuff.

String upToNCharacters = String.format("%."+ n +"s", str);

Awful if n is a variable (so you must construct the format string), but pretty clear if a constant:

String upToNCharacters = String.format("%.10s", str);

docs

Use the substring method, as follows:

int n = 8;
String s = "Hello, World!";
System.out.println(s.substring(0,n);

If n is greater than the length of the string, this will throw an exception, as one commenter has pointed out. one simple solution is to wrap all this in the condition if(s.length()<n) in your else clause, you can choose whether you just want to print/return the whole String or handle it another way.

If you are lucky enough to develop with Kotlin,
you can use take to achieve your goal.

val someString = "hello"

someString.take(10) // result is "hello"
someString.take(4) // result is "hell" )))

ApacheCommons surprised me, StringUtils.abbreviate(String str, int maxWidth) appends "..." there is no option to change postfix. WordUtils.abbreviate(String str, int lower, int upper, String appendToEnd) looks up to next empty space.

I’m just going to leave this here:

public static String abbreviate(String s, int maxLength, String appendToEnd) {
    String result = s;
    appendToEnd = appendToEnd == null ? "" : appendToEnd;
    if (maxLength >= appendToEnd.length()) {
        if (s.length()>maxLength) {
            result = s.substring(0, Math.min(s.length(), maxLength - appendToEnd.length())) + appendToEnd;
        }
    } else {
        throw new StringIndexOutOfBoundsException("maxLength can not be smaller than appendToEnd parameter length.");
    }
    return result;
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top