Substring Then Search

ID

java.substring_then_search

Severity

low

Remediation Complexity

trivial

Remediation Risk

low

Remediation Effort

low

Resource

Efficiency

Language

Java

Tags

efficiency

Description

Reports a call chain str.substring(beginIndex).m(..) where m is indexOf(int), indexOf(String) or startsWith(String).

Rationale

Each of these three methods has an overload that accepts a starting offset directly. Calling substring(beginIndex) first allocates a new String holding the remainder, purely so the search method can be called on it — an allocation, and a full character copy, that buys nothing.

// Bad - allocates a new String just to search inside it
int found = str.substring(beginIndex).indexOf('x');

Remediation

Call the offset-taking overload directly on the original String. For indexOf, subtract beginIndex from the result to get the same index as before.

// Good - no extra allocation; same result once the offset is added back
int found = str.indexOf('x', beginIndex);
if (found >= 0) {
  found -= beginIndex;
}

References

lastIndexOf(x, fromIndex) is not reported. Its second argument is the index to search backwards from, not a begin offset, so s.substring(off).lastIndexOf(x) cannot be rewritten as s.lastIndexOf(x, off) — the two return different answers.

© 2026 Xygeni. All rights reserved