Метод Integer.parseInt () будет принимать строковые представления целых значений со знаком (отрицательных), таких как "- 1024" , и преобразовывать эту строку в INT .На самом деле, он также будет принимать что-то вроде "+ 1024" .То, что он не будет преобразовывать - это пустая строка, пустая строка ("") или любая числовая строка, содержащая один или несколько буквенных символов, включая пробел.Отображаемое сообщение об ошибке указывает на то, что была предпринята попытка передать пустую строку ( "" ) через метод Integer.parseInt () .
ИМХО этохорошая идея проверить строку перед выполнением преобразования, чтобы исключить необходимость генерировать исключение или, по крайней мере, попытаться перехватить исключение и разобраться с ним.
Проверка числовой строкис использованием метода String # match () :
В этом примере используется метод String # match () вместе с регулярным выражением (RegEx) для проверки того факта, что строка, содержащаяся в элементе массива roomString [i] , действительно является строковым представлением целочисленного числового значения со знаком или без знака.Если это не так, то на консоль выводится сообщение об ошибке, и обработка продолжается со следующего элемента массива.
for (int i = 0; i < roomString.length; i++) {
// Trim off an possible leading or trailing whitespaces.
roomString[i] = roomString[i].trim();
if (!roomString[i].matches("\\+?\\d+|\\-?\\d+")) {
System.err.println("The value " + roomString[i] + " located at " +
"index " + i + " can not be converted to Integer!");
continue; // continue processing the remaining array.
}
adjRoomNum[i] = Integer.parseInt(roomString[i]);
System.out.println(adjRoomNum[i]);
//System.out.println((roomString[i]));
}
Используемый RegEx ("\\+?\\d+|\\-?\\d+"
) означает следующее:
\\+?\\d+
Если строка начинается с буквального + символа или нет, а затем следует одна или несколько цифр от 0 до 9 |
ИЛИ \\-?\\d+"
Если строка начинается с буквального символа - или нет, а затем следует одна или несколько цифр от 0 до 9.
Скорее всего, вам может не понадобиться эта часть:\\+?\\d+|
и может оставить его вне выражения.
Перехват исключения NumberFormatException:
for (int i = 0; i < roomString.length; i++) {
// Trim off an possible leading or trailing whitespaces.
roomString[i] = roomString[i].trim();
try {
adjRoomNum[i] = Integer.parseInt(roomString[i]);
}
catch (NumberFormatException ex) {
System.err.println("The value " + roomString[i] + " located at " +
"index " + i + " can not be converted to Integer!");
continue; // continue processing the remaining array.
}
System.out.println(adjRoomNum[i]);
//System.out.println((roomString[i]));
}
Как вы получили пустую строку ("") для начала?
При разборе строки на основе пробелов, особенно если в строке из пользовательского ввода всегда есть вероятность, что двойной пробел был предоставлен где-то или, в вашем случае один ведущий пробел (подробнее об этом позже).Чтобы справиться с этой дилеммой, всегда обрезайте строку с помощью метода String # trim () , чтобы удалить начальные и конечные пробелы перед разбиением этой строки.
Разбор и разбиение ваших конкретных строк:
В целом, ваш синтаксический анализ работает нормально, но вы заметите, что при выполнении этой строки кода:
fullDesc = fullDesc.substring(fullDesc.indexOf(" "));
fullDescПеременная будет содержать целочисленные значения строки с пробелом в начале и в конце, например: " 1 -1 -1 2 "
.Вы не хотите этого, так как это разделится на: "", "1", "-1", "-1", "2"
.Ваш массив roomString будет содержать один элемент Null String из-за начального пробела, а метод Integer.parseInt () не будет обрабатывать те, которые выдают NumberFormatException ,Решение простое, просто добавьте 1 в индекс подстроки или добавьте метод trim () в конец строки кода.Измените приведенную выше строку кода следующим образом:
fullDesc = fullDesc.substring(fullDesc.indexOf(" ") + 1);
O R
// Covers almost all the 'just in case' situations.
fullDesc = fullDesc.substring(fullDesc.indexOf(" ")).trim();
Это, однако, не охватывает возможную ситуацию с двойным интервалом между значениями, когда вы хотите разбить строку, например:
"1 -1 -1 2"
Здесь у нас есть двойной пробел между 1 и -1 и еще раз между -1 и 2. Когда эта строка разбивается на основе одного пробела (String[] roomString = "1 -1 -1 2".split(" ");
), вы получите шесть элементов массива, два изэто будут пустые строки ("1", "", "-1", "-1", "", "2"
), и снова метод Integer.parseInt () в конечном итоге будет выдавать NumberFormatException при обнаружении пустой строки.
Решение, не используйте " "
в вашем методе разделения.Вместо этого используйте "\\s+"
.Это небольшое регулярное выражение указывает методу split () разбивать строку на один или несколько пробелов.
При работе со строковыми цифрами, и вы хотите проанализировать их, используя Integer.parseInt () , Double.parseDouble () или любой другой пробел в числовой строке, вызывающийхаос независимо от того, какой разделитель вы используете.Возьмите этот пример числовой строки с разделителями-запятыми (,), которую Пользователь ввел в консольное приложение:
"1, 2, 3,4,5 ,6 ,7,8 , 9 , 10"
Здесь есть четыре различные ситуации с разделителями:
1) 1, 2
2) 3,4
3) 5 ,6
4) , 9 ,
Если вы быличтобы разделить эту строку, скажем:
String[] values = "1, 2, 3,4,5 ,6 ,7,8 , 9 , 10".split(",");
Ваш массив значений будет содержать:
["1", " 2", " 3", "4", "5 ", "6 ", "7", "8 ", " 9 ", " 10"]
Все элементы массива, которые содержат пробел в них, вызовут NumberFormatException при попытке проанализировать эти элементы с помощью метода Integer.parseInt () .Решение, чтобы охватить все базы, возможно, разделить его так:
String[] values = "1, 2, 3,4,5 ,6 ,7,8 , 9 , 10".split("\\s{0,},\\s{0,}");
Что означает это регулярное выражение: "\\s{0,},\\s{0,}"
?Разделить запятую, даже если до или после запятой есть 0 или более пробелов.
Ваш код может выглядеть следующим образом:
String[] gameStrings = {
"|You're in a large dark room| false 1 -1 -1 2 ",
"|You're in a dark large room| false -1 0 -1 -1 ",
"|You're in a large room, very dark| false 0 0 3 0 ",
"|You're in a dark room, very small| true 0 0 0 0 "
};
for (int s = 0; s < gameStrings.length; s++) {
String fullDesc = gameStrings[s];
String description = fullDesc.substring(1, fullDesc.indexOf("| "));
gameRooms[roomNumber] = new Room(description);
fullDesc = fullDesc.substring(fullDesc.indexOf("| ") + 2);
if (fullDesc.contains("true")) {
gameRooms[roomNumber].putGrail();
}
fullDesc = fullDesc.substring(fullDesc.indexOf(" ")).trim();
String[] roomString = fullDesc.split("\\s+");
Integer[] adjRoomNum = new Integer[roomString.length];
for (int i = 0; i < roomString.length; i++) {
if (!roomString[i].trim().matches("\\+?\\d+|\\-?\\d+")) {
System.err.println("The value " + roomString[i] + " located at "
+ "index " + i + " can not be converted to Integer!");
continue; // Continue processing array elements.
}
adjRoomNum[i] = Integer.parseInt(roomString[i]);
System.out.println(adjRoomNum[i]);
}
}