如何在不检查大小或超出范围的情况下获取字符串的前n个字符?

时间:2021-12-30 21:40:37

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?

如何在不首先进行大小检查(内联是可接受的)或冒着IndexOutOfBoundsException风险的情况下,如何在Java中获取字符串的前n个字符?

7 个解决方案

#1


274  

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.

意见:虽然这个解决方案“整洁”,但我认为它实际上比以明显方式使用if / else的解决方案更不易读。如果读者没有看到这个技巧,他/她必须更加努力地理解代码。 IMO,代码的含义在if / else版本中更为明显。有关更清晰/更易读的解决方案,请参阅@ paxdiablo的答案。

#2


57  

Don't reinvent the wheel...:

不要重新发明*......:

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

Javadoc says:

Javadoc说:

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"

#3


15  

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

Apache Commons Lang为此提供了一个StringUtils.left方法。

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

#4


12  

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

关于SO有一类问题,有时候不太完美,这个问题很危险:-)

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:

如果只是因为你不想用if语句或异常捕获代码来编写你的代码,一种解决方案就是使用一个帮助你的函数来帮助你,比如:

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.

这可能适用于您似乎担心(基于您对其他答案的评论),而不是在执行大量字符串构建时破坏代码流。

#5


7  

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:

如果n是一个变量,那就太可怕了(所以你必须构造格式字符串),但如果是一个常量则非常清楚:

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

docs

文档

#6


5  

Use the substring method, as follows:

使用substring方法,如下所示:

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.

如果n大于字符串的长度,则会抛出异常,正如一位评论者指出的那样。一个简单的解决方案是将所有这些包装在if子句中的if(s.length() )条件中,您可以选择是否只想打印>

#7


-2  

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.

ApacheCommons让我感到惊讶,StringUtils.abbreviate(String str,int maxWidth)附加“...”,没有更改postfix的选项。 WordUtils.abbreviate(String str,int lower,int upper,String appendToEnd)查找下一个空格。

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;
}

#1


274  

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.

意见:虽然这个解决方案“整洁”,但我认为它实际上比以明显方式使用if / else的解决方案更不易读。如果读者没有看到这个技巧,他/她必须更加努力地理解代码。 IMO,代码的含义在if / else版本中更为明显。有关更清晰/更易读的解决方案,请参阅@ paxdiablo的答案。

#2


57  

Don't reinvent the wheel...:

不要重新发明*......:

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

Javadoc says:

Javadoc说:

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"

#3


15  

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

Apache Commons Lang为此提供了一个StringUtils.left方法。

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

#4


12  

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

关于SO有一类问题,有时候不太完美,这个问题很危险:-)

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:

如果只是因为你不想用if语句或异常捕获代码来编写你的代码,一种解决方案就是使用一个帮助你的函数来帮助你,比如:

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.

这可能适用于您似乎担心(基于您对其他答案的评论),而不是在执行大量字符串构建时破坏代码流。

#5


7  

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:

如果n是一个变量,那就太可怕了(所以你必须构造格式字符串),但如果是一个常量则非常清楚:

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

docs

文档

#6


5  

Use the substring method, as follows:

使用substring方法,如下所示:

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.

如果n大于字符串的长度,则会抛出异常,正如一位评论者指出的那样。一个简单的解决方案是将所有这些包装在if子句中的if(s.length() )条件中,您可以选择是否只想打印>

#7


-2  

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.

ApacheCommons让我感到惊讶,StringUtils.abbreviate(String str,int maxWidth)附加“...”,没有更改postfix的选项。 WordUtils.abbreviate(String str,int lower,int upper,String appendToEnd)查找下一个空格。

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;
}