Преобразование String в integers безопасным способом
У меня есть небольшой метод, который, помимо прочего, также преобразует строку в целое число. Поскольку строка является параметром метода, я хочу убедиться, что эта строка может быть конвертируемой. Поэтому я просто задавался вопросом, что будет самым безопасным и/или самым быстрым способом.
Версия A: просто оставьте это как есть и возьмите на себя риски (которых я пытаюсь избежать)
public static int stringToInt(String param) {
return Integer.valueOf(param);
}
(с точки зрения скорости, какая разница в версии B и C?)
Версия B: выхватить исключение
public static int stringToInt(String param) {
try {
return Integer.valueOf(param);
} catch(NumberFormatException e) {
return -1;
}
}
Версия C: проверьте каждую букву строки, чтобы увидеть ее, если это цифра или нет
public static int stringToInt(String param) {
for(char c : param.toCharArray()) {
if(!Character.isDigit(c))
return -1;
}
return Integer.valueOf(param);
}
Обратите внимание, что параметр должен быть положительным числом, а значение -1 должно быть "значением ошибки" в моей маленькой программе, другими словами, все три версии методов будут отлично работать в моей программе.
Я очень открыт для любого другого предложения, которое вы можете мне дать, поэтому не стесняйтесь создавать свою собственную версию, если считаете, что ваша лучше.
Благодарим вас за поддержку.
Ответы
Ответ 1
Во-первых, обратите внимание, что версия C
не является пуленепробиваемой: она будет отклонять отрицательные числа и не будет ловить слишком большие числа.
Версия B
в порядке, но при этом вызывающий абонент меняет стиль кодирования: вместо того, чтобы ловить ошибку и обрабатывать ее вместе с другими ошибками, вызывающему абоненту нужно будет постоянно проверять -1
. Это может быть субоптимальным в ситуациях, когда вы читаете несколько целых чисел, но обработка ошибок не зависит от того, какой из них был неудачным. Кроме того, новые кодеры, использующие ваш API, могут забыть проверить -1
и непреднамеренно использовать код ошибки.
Вот почему я останусь с первым вариантом: код, использующий версию A
, сразу же будет знаком любому, кто знает Java API, без необходимости узнавать, что происходит внутри вашей функции.
Ответ 2
Guava предлагает метод утилиты для этого, который возвращает null в случае, если ваша строка не может быть проанализирована.
https://google.github.io/guava/releases/19.0/api/docs/com/google/common/primitives/Ints.html#tryParse(java.lang.String)
Integer result = Ints.tryParse("1"); //returns 1
Integer result = Ints.tryParse("-1"); //returns -1
Integer result = Ints.tryParse("a"); //returns null
Ответ 3
Я полагаю, что лучшим вариантом будет модифицированный B, чтобы исключить исключение, а не возвращать -1. Хорошо исключить исключение до уровня, где его можно обработать, чтобы отправить правильный ответ пользователю. Возврат значения, равного -1, сделает вашу ошибку кода неприемлемой. Предположим, что другой программист использует ваш метод, и он/она просто имеет подпись вашего метода. Поэтому из подписи неясно, что он/она должен кодировать для обработки сценария исключения или ошибки. Но если вы выбросите исключение и добавите его в объявление метода, он позволит другому программисту правильно использовать ваш метод вместе с необходимой обработкой исключений. Для меня это выглядит лучше:
public static int stringToInt(String param) throws NumberFormatException {
try {
return Integer.valueOf(param);
} catch(NumberFormatException e) {
// return -1;
throw e;
}
}
Ответ 4
Java 8 без API:
Optional.ofNullable(strNum)
.map(Integer::valueOf).orElse(null);