[英]Is there a way to ignore a string if it cannot be parseInt without try and catch?
[英]Way to parseInt without try-catch in Java 8?
有沒有更好的方法來嘗試將一個可以是或不是整數的字符串轉換為 int ? Integer.parseInt(String value) 將適用於“25”或“019”,但不適用於“hello”或“8A”。 在 Java 8 中,我們有可選值,例如:
public static void main(String[] args) {
Optional<Integer> optionalResult = functionThatReturnsOptionalInteger();
Integer finalValue = optionalResult.orElse(0);
System.out.println(finalValue);
}
public static Optional<Integer> functionThatReturnsOptionalInteger() {
Integer[] ints = new Integer[0];
return Stream.of(ints).findAny();
}
您不需要檢查空值,因為Optional
包裝器公開了處理這種情況的有用方法。
但是如果你想parseInt
一個字符串,它可以是空的,或者不包含一個有效的整數,解決方案和往常一樣:
public static Integer parseIntOrDefault(String toParse, int defaultValue) {
try {
return Integer.parseInt(toParse);
} catch (NumberFormatException e) {
return defaultValue;
}
}
如何使用 Java 8 功能改進這一點,為什么 Integer.parseInt() 沒有被重載以在參數錯誤的情況下返回 Optional ? (或者只是添加一個新方法 Integer.parseIntOptional() 到 Integer 包裝器)
標准庫 afaik 中不存在這樣的東西,但是您可以編寫一個方法,將String
解析為Optional<Integer>
如下所示:
public static Optional<Integer> parseInt(String toParse) {
try {
return Optional.of(Integer.parseInt(toParse));
} catch (NumberFormatException e) {
return Optional.empty();
}
}
與現在已刪除的其他答案不同,我不認為這真的與 Java 向后兼容有關。
因為一個空的Optional
代表一個不存在的值,這意味着該方法實際上有效但沒有返回任何結果。
但是,將hello
解析為整數將不起作用並且必須拋出異常,因為它是錯誤而不是空結果。 請記住, NumberFormatException
擴展了IllegalArgumentException
。
更一般地說, Optional
用於處理可能不存在的值(而不是為此使用null
),而不是用於錯誤處理。 此外, Optional
沒有提供任何方法來了解錯誤是什么以及為什么會出現錯誤。
我不想推測為什么這樣的方法不存在,但如果你既不喜歡,執行預測試也不捕獲異常,你需要重新實現,例如
public static OptionalInt parseInt(String s) {
if(s.isEmpty()) return OptionalInt.empty();
final int len = s.length(), limit;
final boolean negative;
int i = 0;
switch(s.charAt(0)) {
case '-':
i=1;
if(len==1) return OptionalInt.empty();
negative = true;
limit = Integer.MIN_VALUE;
break;
case '+':
i=1;
if(len==1) return OptionalInt.empty();
// fall-through
default:
negative = false;
limit = -Integer.MAX_VALUE;
}
final int limitBeforeMul = limit / 10;
int result = 0;
for(; i < len; i++) {
int digit = Character.digit(s.charAt(i), 10);
if(digit < 0 || result < limitBeforeMul || (result *= 10) < limit + digit)
return OptionalInt.empty();
result -= digit;
}
return OptionalInt.of(negative? result: -result);
}
這基本上與Integer.parseInt
相同,但為無效字符串返回一個空的OptionalInt
而不是拋出異常......
您可能已經注意到,最難的部分是處理接近於Integer.MIN_VALUE
數字。 Integer.MAX_VALUE
正確。
沒有 try-catch 並且仍然返回一個 Optional - 你可以做
Optional<Integer> result = Optional.ofNullable(input)
.filter(str -> str.matches("-?\\d+"))
.map(Integer::parseInt);
編輯:更新正則表達式以支持負數
警告:如評論中所指出的,如果解析的字符串超出Integer.MIN_VALUE
和Integer.MAX_VALUE
的范圍,仍將拋出 RuntimeException
Google 的 Guava 庫提供了一個輔助方法來執行此操作:Ints.tryParse(String)。當字符串不可解析時,它會運行null
。 您可以查看文檔。
使用Mutiny可以這樣寫。
如果你只是想對結果做一些事情,你可以用一個表達式來做
Uni.createFrom()
.item(() -> Integer.parseInt(toParse))
.onFailure().recoverWithItem(defaultValue)
.subscribe().with(i -> System.out.println(i));
或者創建一個像預期的方法
public static Integer parseIntOrDefault(String toParse, int defaultValue) {
Integer[] toReturn = new Integer[]{null};
Uni.createFrom()
.item(() -> Integer.parseInt(toParse))
.onFailure().recoverWithItem(defaultValue)
.subscribe().with(i -> toReturn[0] = i);
return toReturn[0];
}
此解決方案添加了一個庫,但該庫並非專門用於處理此問題。 它使用反應式編程、期貨、回調和流暢的 API,並被證明足夠靈活來解決這個問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.