Пока автор Java string.indexOf
не расскажет нам реальную историю ...
Давайте предположим, что мы должны были разработать его с нуля, некоторые очевидные ограничения дизайна для этой проблемы:
indexOf
должен возвращать числовое значение, чтобы при обнаружении совпадения вы знали, где оно находится
- действительные индексы всегда гарантируются целыми числами
- индексы массива (и строки) в Java начинаются с нуля
- Java строго типизирован
- целочисленные числовые типы подписаны в Java
Учитывая эти основные ограничения, некоторые возможные варианты для функции, возвращающей тип, будут целочисленными (в идеале такого типа, который достаточно большой, чтобы представлять последний индекс в максимально возможной строке), ИЛИ ... Object
(и, возможно, возвращать ноль указать не найдено). Но на практике возврат Object
не будет ни эффективным, ни удобным для пользователя, из-за необходимости проверять его действительность и приводить перед использованием для найденного случая - так что это на самом деле не жизнеспособный вариант!
Итак, давайте перейдем к целому числу. Мы хотим выбросить исключение, если не найдено? Бросание исключений имеет множество собственных проблем - создание объектов исключений и переход к обработчикам исключений могут быть весьма неэффективными, и написание блоков try / catch вокруг вызовов indexOf
также не доставляет удовольствия!
Итак, допустим, мы сузили его: он должен возвращать (целочисленный) целочисленный тип, а не вызывает исключение. Теперь, какое целое значение должно возвращаться для представления не найден?
Чтобы разрешить поиск в строках как можно большего размера, мы должны зарезервировать все положительные целые числа для использования в качестве значения успешно найденного. И наоборот, ни одно из отрицательных чисел не требуется для представления индекса «найдено», поэтому все они потенциально доступны для использования в качестве кодов возврата, представляющих «не найдено».
Если бы мы могли выбрать любое отрицательное число, чтобы представить его не найденным, или просто сказать «все отрицательные возвращаемые значения означают, что он не найден», это бы сработало ... Но будет ли это лучший дизайн?
Какие причины использовать -1 вместо других отрицательных чисел? Мои любимые причины: «-1 легко запомнить, и вы можете провести точные проверки на равенство». (Вместо того, чтобы быть вынужденным использовать неравенства и думать об однозначных проблемах, например, хотите ли вы меньше или меньше или равны, и с каким значением сравнивать, ноль или минус)
Я также иногда восхищаюсь доводом Криса, что (перефразируя) «он прекрасно работает с substring(foundIndex + 1)
».