Java 如何在不检查大小或越界的情况下获取字符串的前 n 个字符?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1583940/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 16:29:04  来源:igfitidea点击:

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

javastringindexoutofboundsexception

提问by antony.trupe

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

如何n在不先进行大小检查(内联是可以接受的)或冒IndexOutOfBoundsException?

采纳答案by Stephen C

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 readablethan a solution that uses if/ elsein the obvious way. If the reader hasn't seen this trick, he/she has to think harderto understand the code. IMO, the code's meaning is more obvious in the if/ elseversion. For a cleaner / more readable solution, see @paxdiablo's answer.

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

回答by Matt Boehm

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 elseclause, you can choose whether you just want to print/return the whole String or handle it another way.

如果 n 大于字符串的长度,这将引发异常,正如一位评论者指出的那样。一个简单的解决方案是将所有这些都包装if(s.length()<n)在您的else子句中的条件中,您可以选择是只想打印/返回整个字符串还是以另一种方式处理它。

回答by paxdiablo

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 ifstatements 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.

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

回答by Nickkk

Don't reinvent the wheel...:

不要重新发明轮子...:

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

Javadocsays:

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"
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"

回答by 13ren

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

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

可怕的 ifn是一个变量(所以你必须构造格式字符串),但很清楚如果是一个常量:

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

docs

文档

回答by Skuli

Apache Commons Langhas a StringUtils.leftmethod for this.

Apache Commons Lang对此有一个StringUtils.left方法。

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

回答by yuceel

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)附加“...”没有更改后缀的选项。 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;
}

回答by Leo Droidcoder

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

如果你有幸使用 Kotlin 进行开发,
你可以使用它take来实现你的目标。

val someString = "hello"

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

回答by Touhid

Kotlin: (If anyone needs)

Kotlin:(如果有人需要)

var mText = text.substring(0, text.length.coerceAtMost(20))