-1 as a return value is slightly ugly but necessary. The alternatives to signal a "not found" condition are IMHO all much worse:
You could throw an Exception, but
this isn't ideal because Exceptions
are best used to signal unexpected
conditions that require some form of
recovery or propagated failure. Not
finding an occurrence of a substring
is actually pretty expected. Also
Exception throwing has a significant
performance penalty.
You could use a compound result
object with (found,index) but this
requires an object allocation and
more complex code on the part of the
caller to inspect the result.
You could separate out two separate
function calls for contains and indexOf - however this is
again quite cumbersome for the caller
and also results in a performance hit
as both calls would be O(n) and
require a full traversal of the
String.
Personally, I never like to refer to the -1 constant: my test for not-found is always something like:
int i = someString.indexOf("substring");
if (i>=0) {
// do stuff with found index
} else {
// handle not found case
}