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
?

- 10,640
- 10
- 57
- 84
-
1unless you catch the exception, I don't know how you plan to handle the case where the character length is greater than the String length. – Matt Boehm Oct 18 '09 at 03:52
-
3Why? What's your aversion to checking length or catching an exception? – paxdiablo Oct 18 '09 at 03:57
-
1OUt of curiosity, why do you want to avoid the size check. This is not C. – Tom Hawtin - tackline Oct 18 '09 at 03:59
-
what I meant to express was a desire to avoid an if/else block, not an aversion to actually checking length. – antony.trupe Oct 18 '09 at 04:22
-
potential duplicate of : https://stackoverflow.com/questions/8499698/trim-a-string-based-on-the-string-length/35252333#35252333 – Whimsical Feb 12 '19 at 23:37
-
the absolute simplest is just by making sure your string is longer by appending spaces to the end first. – John Lord Apr 20 '22 at 15:54
8 Answers
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.

- 698,415
- 94
- 811
- 1,216
-
1+1. Even better if this is wrapped in a function named safe_substring or substring_safe, like paxdiablo's answer, so that usage is easier to read / intent more obvious. – ToolmakerSteve Aug 20 '14 at 05:17
-
3I disagree with what you are saying. If this is wrapped in a function, *it doesn't matter what is inside the function*, and any "neatness" is definitely out-weighed by lack of clarity. The point of this solution is that it is "neat" for the case where you *don't* want to create a wrapper function. – Stephen C Jun 19 '18 at 11:42
-
It would be neater to use StringUtils. It prevents both IndexOutOfBoundsException and NullPointerException. – Lluis Martinez May 19 '21 at 15:02
-
I'm not convinced that preventing NPEs is a good thing. An NPE means you should have a `null` in `s`. It is a sign of a bug, not something that should be hidden. Dealing with a `null` is not part of the OP's stated requirements. – Stephen C May 20 '21 at 07:50
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"

- 30,436
- 41
- 178
- 315

- 1,119
- 1
- 7
- 2
-
1It doesn't answer the question, but regardless it still provides the solution. If the OP is able to understand, I think this is a better solution. – aullah Mar 09 '14 at 23:43
-
7It might also be useful to point out that `StringUtils.substring(yourString, 0, n)` is not the same as `yourString.substring(0, n)`. The former is from `StringUtils`, while the latter is using `String.substring` (which gives exception if end index exceeds string length). – ToolmakerSteve Aug 20 '14 at 04:59
-
Just as FYI if you look in the source for this method its handling the case where the end is greater than the length by changing the end to the length: `if (end > str.length()) { end = str.length();}` – bholl Apr 05 '17 at 19:14
-
2The last Parameter of `StringUtils.substring(String s, int start, int len)` is not len, it is the end-Index. – gorootde Apr 10 '17 at 10:27
-
Apache Commons Lang has a StringUtils.left
method for this.
String upToNCharacters = StringUtils.left(s, n);

- 1,997
- 2
- 20
- 28
-
1
-
4
-
-
4@DoWill: Because adding an(other) 3rd-party library to your executable environment is not always worthwhile. – LarsH Oct 28 '19 at 16:08
-
@LarsH But Apache Commons, as it is populate, had already included in many many projects already. It would not be adding yet another 3rd party library for partially string slicing. – tsh Jul 28 '21 at 07:53
-
1@tsh I agree, in those cases, using Apache Commons is a very good option. But there are also many projects that don't already use AC. – LarsH Jul 28 '21 at 14:25
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);

- 11,887
- 9
- 47
- 64
-
Interesting alternative, though I can't imagine ever using it, given the more traditional approaches, that were given four years ago. – ToolmakerSteve Aug 20 '14 at 05:14
-
Best answer because the input String is read only once, so there's no need to store it in a variable, which makes it possible to embed it neatly. – Profiterole Aug 18 '19 at 13:40
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.

- 854,327
- 234
- 1,573
- 1,953
-
2+1: This is a MUCH better approach than the accepted one, given OP's desire to not clutter the code. (or see Nickkk's solution of including a library that already has a function that behaves as desired.) – ToolmakerSteve Aug 20 '14 at 05:04
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.

- 1,894
- 1
- 18
- 21
-
1
-
By the way, if you plan on programming in Java, you should try to memorize most of the API methods for String (http://java.sun.com/j2se/1.5.0/docs/api/java/lang/String.html). – Matt Boehm Oct 18 '09 at 03:48
-
I've already ruled out substring, at least by itself, as _not_ the answer. – antony.trupe Oct 18 '09 at 03:49
-
You have to either check the size or catch the exception. May I ask why doing either of these would not work in your situation? – Matt Boehm Oct 18 '09 at 03:54
-
in the middle of building a string. they'd work, just would break up the flow of the code. – antony.trupe Oct 18 '09 at 04:00
-
@Matt - it is better to design your algorithm so that exceptions don't occur. Firstly, creating and catching exceptions can be expensive operations. Secondly, exception handling can be complicated, especially if there are resources that need to be closed / freed / etc. – Stephen C Oct 18 '09 at 04:04
-
3How is this an answer to the question? The question was asking how to NOT have to do a size check first, nor cause an exception that needs to be caught. – ToolmakerSteve Aug 20 '14 at 05:22
Another great compact way, without having to use a third party library, would be to use the ternary operator (?:):
s = s.length() > n ? s.substring(0, n) : s;
but it might be just as simple to use a "one-line" if-statement:
if (s.length() > n) s = s.substring(0, n);

- 544
- 1
- 8
- 14
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;
}

- 1,943
- 2
- 18
- 27
-
1@VolkanGüven It's because of this "ApacheCommons surprised me" sentence. I commited sin via critisizing holy ApacheCommons library. Or whatever... – yuceel Oct 11 '18 at 14:35