NumberOptional:一个字符串转数字的工具
在做Java开发中,我们经常会写下下面这样的代码:
try {
int i = Integer.parseInt(s);
} catch (NumberFormatException e) {
e.printStackTrace();
}
这段代码信息量只有一行,但是写起来就比较多了。每次都写就比较繁琐,如果不加try-catch又显得不严谨、不安全。于是,很多人选择封装一个数字操作相关的工具,比如各种各样的数字Util,操作的代码就变成了:
int i1 = NumberUtil.parseInt(s);//解析失败,默认返回0
int i2 = NumberUtil.parse(s, 0);//提供一个默认值,在解析失败的时候返回。
Optional<Integer> intOpt = NumberUtil.parseInt(s);//用Optional来表示解析失败为空的情况
//....
上面第一种方式不用说了,无法控制默认值使得在一些场景不适用;第二种方式,可以控制默认值,但是当值域为所有整数时,无法区分解析失败的情况。本文分享一个以前用来处理字符串转数字的工具。
使用示例
因为功能比较简单,所以直接上示例代码:
String s = "1";
String s2 = "2";
//1. getOr等重载根据提供的默认值类型来解析,如果不符合就返回提供的默认值
int i1 = NumberOptional.of(s).getOr(1);
float f1 = NumberOptional.of(s).getOr(1f);
//2. orGetXXX系列的方法用于处理默认值并非固定值,或者获取默认值的方法有些麻烦的情况。根据默认值的类型来解析字符串
int i2 = NumberOptional.of(s).orGetInt(() -> Config.getXXXDefault());
//3. xxxOr系列的方法用于从多个字符串取合适的值的情况,例如,如果s可用就用s的值,否则s2的值,如果s2的值还是不可用,就用默认值。
int i3 = NumberOptional.of(s).intOr(() -> NumberOptional.of(s2)).getOr(0);
//4. ifXXX的方法用于后面的操作仅在解析成功时执行的情况,如果失败则什么都不做
NumberOptional.of(s).ifInt(i -> {
System.out.println("is Int:" + i);
});
//5. ifXXXOrElse系列的方法类似ifXXX,不过可以提供一个过程在解析失败的时候执行。
NumberOptional.of(s).ifIntOrElse(i -> {
System.out.println("is int:" + i);
}, () -> {
System.out.println("is not int");
});
parseOr
public class NumberOptional {
private final String valueString;
private NumberOptional() {
this.valueString = null;
}parseOr
private NumberOptional(String valueString) {
this.valueString = valueString;
}
public static NumberOptional of(String numberStr) {
return new NumberOptional(numberStr);
}
public static NumberOptional of(Object object) {
return new NumberOptional(String.valueOf(object));
}
public NumberOptional longOr(Supplier<? extends NumberOptional> supplier) {
return parseOr(Long::parseLong, supplier);
}
public NumberOptional intOr(Supplier<? extends NumberOptional> supplier) {
return parseOr(Integer::parseInt, supplier);
}
public NumberOptional floatOr(Supplier<? extends NumberOptional> supplier) {
return parseOr(Float::parseFloat, supplier);
}
public NumberOptional doubleOr(Supplier<? extends NumberOptional> supplier) {
return parseOr(Double::parseDouble, supplier);
}
public NumberOptional shortOr(Supplier<? extends NumberOptional> supplier) {
return parseOr(Short::parseShort, supplier);
}
public NumberOptional byteOr(Supplier<? extends NumberOptional> supplier) {
return parseOr(Byte::parseByte, supplier);
}
public long getOr(long defaultValue) {
return parseOrElse(Long::parseLong, defaultValue);
}
public int getOr(int defaultValue) {
return parseOrElse(Integer::parseInt, defaultValue);
}
public short getOr(short defaultValue) {
return parseOrElse(Short::parseShort, defaultValue);
}
public byte getOr(byte defaultValue) {
return parseOrElse(Byte::parseByte, defaultValue);
}
public float getOr(float defaultValue) {
return parseOrElse(Float::parseFloat, defaultValue);
}
public double getOr(double defaultValue) {
return parseOrElse(Double::parseDouble, defaultValue);
}
public long orGetLong(Supplier<Long> supplier) {
return parseOrElseGet(Long::parseLong, supplier);
}
public int orGetInt(Supplier<Integer> supplier) {
return parseOrElseGet(Integer::parseInt, supplier);
}
public short orGetShort(Supplier<Short> supplier) {
return parseOrElseGet(Short::parseShort, supplier);
}
public byte orGetByte(Supplier<Byte> supplier) {
return parseOrElseGet(Byte::parseByte, supplier);
}
public float orGetFloat(Supplier<Float> supplier) {
return parseOrElseGet(Float::parseFloat, supplier);
}
public double orGetDouble(Supplier<Double> supplier) {
return parseOrElseGet(Double::parseDouble, supplier);
}
public void ifLongOrElse(Consumer<Long> parsedConsumer, Runnable elseRunnable) {
ifParseOrElse(Long::parseLong, parsedConsumer, elseRunnable);
}
public void ifIntOrElse(Consumer<Integer> parsedConsumer, Runnable elseRunnable) {
ifParseOrElse(Integer::parseInt, parsedConsumer, elseRunnable);
}
public void ifShortOrElse(Consumer<Short> parsedConsumer, Runnable elseRunnable) {
ifParseOrElse(Short::parseShort, parsedConsumer, elseRunnable);
}
public void ifByteOrElse(Consumer<Byte> parsedConsumer, Runnable elseRunnable) {
ifParseOrElse(Byte::parseByte, parsedConsumer, elseRunnable);
}
public void ifFloatOrElse(Consumer<Float> parsedConsumer, Runnable elseRunnable) {
ifParseOrElse(Float::parseFloat, parsedConsumer, elseRunnable);
}
public void ifDoubleOrElse(Consumer<Double> parsedConsumer, Runnable elseRunnable) {
ifParseOrElse(Double::parseDouble, parsedConsumer, elseRunnable);
}
public void ifLong(Consumer<Long> parsedConsumer) {
ifParse(Long::parseLong, parsedConsumer);
}
public void ifInt(Consumer<Integer> parsedConsumer) {
ifParse(Integer::parseInt, parsedConsumer);
}
public void ifShort(Consumer<Short> parsedConsumer) {
ifParse(Short::parseShort, parsedConsumer);
}
public void ifByte(Consumer<Byte> parsedConsumer) {
ifParse(Byte::parseByte, parsedConsumer);
}
public void ifFloat(Consumer<Float> parsedConsumer) {
ifParse(Float::parseFloat, parsedConsumer);
}
public void ifDouble(Consumer<Double> parsedConsumer) {
ifParse(Double::parseDouble, parsedConsumer);
}
public String get() {
return valueString;
}
private <T> T parseOrElseGet(Function<String, T> parser, Supplier<T> supplier) {
try {
return parser.apply(valueString);
} catch (NumberFormatException | NullPointerException e) {
return supplier.get();
}
}
private <T> T parseOrElse(Function<String, T> parser, T defaultValue) {
try {
return parser.apply(valueString);
} catch (NumberFormatException | NullPointerException e) {
return defaultValue;
}
}
private <T> NumberOptional parseOr(Function<String, T> parser, Supplier<? extends NumberOptional> supplier) {
try {
T i = parser.apply(valueString);
return this;
} catch (NumberFormatException | NullPointerException e) {
return supplier.get();
}
}
private <T> void ifParseOrElse(Function<String, T> parser, Consumer<T> parsedConsumer, Runnable elseRunnable) {
final T i;
try {
i = parser.apply(valueString);
} catch (NumberFormatException | NullPointerException e) {
elseRunnable.run();
return;
}
parsedConsumer.accept(i);
}
private <T> void ifParse(Function<String, T> parser, Consumer<T> parsedConsumer) {
final T i;
try {
i = parser.apply(valueString);
} catch (NumberFormatException | NullPointerException e) {
return;
}
parsedConsumer.accept(i);
}
}