I've got a bit of code that I'm wanting to tidy up. The aim is to take a String
that consists of multiple words connected by a separator (It's produced using Collectors.joining(SEPARATOR)
as below, although the stream processing is not quite so trivial), and return a portion from the front of it.
This portion should never contain partial words, but should in most cases be less than the TARGET_LENGTH
number of total characters. It is safe to assume that the words themselves do not contain the SEPARATOR
character.
String SEPARATOR = "-";
int TARGET_LENGTH = 20;
//Expected output: "this-is-a-sample"
String s = Arrays.asList("this", "is", "a", "sample", "string")
.stream()
.collect(Collectors.joining(SEPARATOR));
if (s.length() > TARGET_LENGTH) {
if (s.contains(SEPARATOR)) {
if (s.substring(0, TARGET_LENGTH + 1).contains(SEPARATOR)) {
return s.substring(0, s.substring(0, TARGET_LENGTH + 1).lastIndexOf(SEPARATOR));
} else {
return s.substring(0, s.indexOf(SEPARATOR));
}
}
}
return s;
Expected output is as follows:
s || result
"easy" || "easy"
"simple-case" || "simple-case"
"very-long-input-will-be-truncated" || "very-long-input-will"
"countercountermeasures" || "countercountermeasures" //Longer than 20 chars
"countercountermeasures-foo-bar-baz"|| "countercountermeasures" //Longer than 20 chars
"a-b-c-d-e-f-g-veryveryverylongword"|| "a-b-c-d-e-f-g"
The provided code works, but isn't very clear and I imagine it will be horrible to maintain if any requirements change in the future. I'm looking for suggestions as to how it could be improved. I've considered adding a filter to the Stream
that generates the String
, with a counter keeping track of the current output length declared outside of the string-generation, but this feels like an even worse thing to do (At a guess I'd have to do something silly like update the counter from within a call to Stream.map()
)