Как извлечь из строки только цифры без использования регулярных выражений в Java
Что проверяют
Умеете ли вы решить простую задачу аккуратно: одним проходом, без лишних аллокаций и с пониманием, что такое «цифра» в Java. Следом почти всегда спрашивают, что вернёт ваш код на строке с арабскими или полноширинными цифрами и как получить из результата число.
Как отвечать
Базовое решение: пройти строку циклом по charAt(i) и складывать подходящие символы в StringBuilder, заранее задав ёмкость new StringBuilder(s.length()). Сложность O(n) по времени и по памяти. Дальше покажите, что понимаете выбор проверки:
c >= '0' && c <= '9': только ASCII-цифры. Подходит, когда по условию нужны именно символы от 0 до 9;Character.isDigit(c): любые символы категории Unicode Nd, включая'٣'и'3'. Если результат дальше уходит в базу или в сравнение с ASCII, это сюрприз;codePoints():chars()иcharAtработают с единицами UTF-16, а цифры из дополнительных плоскостей Unicode занимают пару суррогатов. Для полной корректности беритеs.codePoints().filter(Character::isDigit)иappendCodePoint.
Вариант на стримах: s.chars().filter(c -> c >= '0' && c <= '9').collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append).toString(). Он короче, но на горячем пути цикл обычно быстрее. Ещё вариант без StringBuilder: заполнить char[] и вернуть new String(buf, 0, len).
Если нужно число, а не строка, копите его сразу: value = value * 10 + (c - '0'), через Math.multiplyExact и Math.addExact, чтобы переполнение long бросило исключение, а не дало мусор. Для длинных последовательностей подойдёт new BigInteger(digits).
Где спотыкаются
Склеивают результат через result += c в цикле. Каждая итерация создаёт новую строку, и на длинном входе решение становится квадратичным.
Путают Character.isDigit с проверкой диапазона или берут Character.getNumericValue(c) >= 0, которая считает цифрами и латинские буквы: для 'a' она вернёт 10.
Не проговаривают крайние случаи: null, пустая строка, строка без цифр, ведущие нули и переполнение при переводе в число.