Рубрики
Без рубрики

Будьте осторожны с методом подстроки строки в Java

Как учитель, я хотел бы предупредить своих учеников о различных подводных камнях в информатике. Сегодня давайте поговорим о методе подстроки Java. С пометкой java, учебник, новички, программирование.

Кодирующие касательные (Серия из 10 частей)

Время от времени я буду сталкиваться с хорошо зарекомендовавшей себя библиотекой на языке программирования, у которой есть свои причуды. Как инструктор, я должен быть уверен, что знаю об этих причудах, когда преподаю. Например, в прошлый раз Я немного рассказал о различных методах ввода сканера и как они не все ведут себя одинаково. Что ж, сегодня я хочу поговорить о методе подстроки из библиотеки строк Java .

Документация

При первом использовании библиотеки я нахожу полезным ознакомиться с документацией. Но с такой устоявшейся библиотекой иногда кажется глупым копаться в документации. В конце концов, многие языки поддерживают строки. Лично мне нужно знать только название команды, прежде чем я смогу разобраться с остальным.

Однако время от времени я сталкиваюсь с функцией, которая менее интуитивно понятна, чем я думал. В данном случае я говорю о методе подстроки Java. Как вы, наверное, можете себе представить, он берет подстроку из строки и возвращает ее. Итак, в чем же подвох?

Ну, для начала, метод подстроки на самом деле является перегруженным методом. В результате в документации присутствуют две разные формы одного и того же метода. Посмотри:

подстрока общедоступной строки(int beginIndex)

Возвращает новую строку, которая является подстрокой этой строки. Подстрока начинается с символа с указанным индексом и продолжается до конца этой строки.

Java API, 2019

подстрока открытой строки(int beginIndex, int endIndex)

Возвращает новую строку, которая является подстрокой этой строки. Подстрока начинается с указанного beginIndex и продолжается до символа с индексом endIndex - 1 . Таким образом , длина подстроки равна endIndex-beginIndex .

Java API, 2019

На этом этапе не зацикливайтесь слишком сильно на их описаниях, так как мы к ним еще вернемся. Просто имейте в виду, что существуют две разные версии одного и того же метода.

Использование

На этом этапе я хотел бы воспользоваться моментом, чтобы показать, как использовать метод подстроки. Если вы впервые знакомитесь с Java API, сейчас самое подходящее время последовать его примеру.

Во-первых, обратите внимание, что заголовок метода не содержит ключевого слова static. Другими словами, подстрока – это метод экземпляра, который имеет смысл. Нам нужен экземпляр строки, чтобы получить подстроку:

String str = "Hello, World!";
String subOne = str.substring(7);
String subTwo = str.substring(0, 5);

В этом примере мы создали две новые подстроки: одну с позиции 7 до конца, а другую с позиции 0 до позиции 5. Не заглядывая в документацию, можете ли вы определить, какими будут результирующие строки?

Обозначение интервалов

Прежде чем я дам ответ, я думаю, что важно обсудить некоторую терминологию из математики. В частности, я хотел бы немного поговорить об интервальной нотации.

В интервальной нотации цель состоит в том, чтобы явно указать диапазон некоторого подмножества. Например, нас могут интересовать все целые числа, большие 0. В интервальной нотации это выглядело бы примерно так:

(0, +∞)

В этом примере мы решили исключить значение 0 из диапазона, используя круглые скобки. Мы могли бы так же легко определить интервал, начинающийся с 1 — обратите внимание на скобки:

[1, +∞)

В любом случае мы описываем один и тот же набор: все целые числа больше 0.

Итак, как это связано с методом подстроки? Как оказалось, подстрока – это подмножество строки, поэтому мы можем использовать интервальную нотацию для определения нашей подстроки. Почему бы нам не попробовать привести пару примеров? Учитывая “Привет, мир!”, определите подстроку, используя следующие интервалы:

  • [0, 2]
  • (0, 5]
  • (1, 3)
  • (-1, 7]

Как только вы закончите, ознакомьтесь с ответами ниже:

  • “Хель”
  • “привет,”
  • “l”
  • “Привет, В”

Нам нужно будет держать эту идею в глубине вашего сознания, двигаясь вперед.

правда

Правда в том, что метод подстроки немного странный. С одной стороны, мы можем использовать один индекс для указания начальной точки нашей новой подстроки. С другой стороны, мы можем использовать два индекса для захвата произвольного подмножества строки.

Однако на практике я нахожу, что второй вариант доставляет много хлопот студентам, и я их не виню. В конце концов, границы обманчивы. Например, давайте вернемся к некоторому коду сверху:

String str = "Hello, World!";
String subOne = str.substring(7);
String subTwo = str.substring(0, 5);

Здесь мы можем с уверенностью предсказать, что sub One имеет значение “Мир!”, и мы были бы правы. В конце концов, индекс 7 равен “W”, метод автоматически захватывает остальную часть строки.

Что касается sub Two , мы, вероятно, предположили бы “Привет”, и мы были бы неправы. На самом деле это “Привет”, потому что конечный индекс является эксклюзивным (т.Е. [0, 5)). В следующем разделе мы рассмотрим, почему это так и как я к этому отношусь.

Мой Дубль

Насколько я понимаю, инклюзивная/эксклюзивная модель является стандартом для диапазонов в Java API. Тем не менее, я иногда сомневаюсь в выборе дизайна.

С одной стороны, преимущество заключается в возможности использовать длину строки в качестве конечной точки подстроки:

String jokerQuote = "Madness, as you know, is like gravity, all it takes is a little push.";
String newtonTheory = jokerQuote.substring(30, jokerQuote.length());

Но действительно ли это необходимо? Java уже предоставляет перегрузку методу подстроки, который фиксирует именно это поведение.

Тем не менее, для этой записи есть хорошее математическое объяснение, и часть его связана с разницей между начальной и конечной точками. В частности, мы получаем длину новой подстроки:

int length = endIndex - startIndex;

Кроме того, эта конкретная нотация позволяет соседним подстрокам разделять среднюю точку:

String s = "Luck is great, but most of life is hard work.";
String whole = s.substring(0, s.length()/2) + s.substring(s.length()/2, s.length());

Оба эти свойства хороши, но я думаю, что они, скорее всего, являются побочным продуктом индексации по нулю ( увековечено Дейкстрой ), что тоже не так интуитивно понятно . И для тех из вас, кто собирается возразить против этого комментария, имейте в виду, что я полностью за индексацию по нулю и за это соглашение об инклюзивном/исключительном подмножестве.

Все, что я пытаюсь сказать, это то, что я видел, как мои собственные ученики спотыкались об обе конвенции, поэтому я в некотором смысле сочувствую им. Вот почему я проделал такой долгий путь, чтобы написать эту статью в первую очередь.

Дай мне знать, если ты чувствуешь то же самое или я совсем не в себе. В противном случае, спасибо, что нашли время прочитать мою работу. Надеюсь, вам это понравилось!

Кодирующие касательные (Серия из 10 частей)

Оригинал: “https://dev.to/renegadecoder94/be-careful-with-strings-substring-method-in-java-gjg”