java 浮点 字符串_关于浮点数:如何将字符串转换为浮点数,并避免在Java中使用try / catch?...

在某些情况下,我需要将字符串转换为float或其他一些数值数据类型,但是有可能会得到一些不可转换的值,例如"-"或" /",并且我无法事先验证所有值以将其删除 他们。

并且我想避免对此问题使用try / catch,还有其他方法可以在Java中进行正确的转换吗? 与C#TryParse类似吗?

为什么人为约束无例外? AFAIK,您必须自己动手!

查看stackoverflow.com/a/1102916/1071777 CraigTP的isNumeric方法基本上是tryParse(您可以根据需要进行修改)

它不是我自己来钓取来自某处的基于I / O的数据,所以我必须使其理智

问题是:如果它不可靠,您肯定想快速失败而不继续吗?

@Nim,我根本不称其为人为约束,只是简单地探索一下Java中是否存在与.NETs TryParse中类似的避免异常功能。

@austinpowers如果您不想利用框架并捕获异常,为什么不只使用正则表达式来验证字符串是否是您想要的?明确定义了异常,以指出数字格式不正确。您在这里与框架作斗争。

@AnthonyPegram,嗯,对我来说似乎很浪费时间...捕获异常并进行处理-肯定比任何其他骇客方法要快得多...

@Nim,如果您牢记从C#角度出发,那么"更快"的主张将是错误的。当处理不正确的输入时,float.TryParse快几个数量级。异常处理很慢,我们也不喜欢依赖异常进行控制流。因此,由于Austin从C#角度出发,所以他在寻找相同的快速,非例外的输入验证,同时提供输出。您只能通过寻求指导来了解它在Java中不存在!

@安东尼真的吗?异常处理慢吗?是的,在例外情况下可以,但是要避免,您宁愿以相同的开销执行所有操作?

@Nim,您为什么认为.NET中的TryParse会带来很多开销?为了得出该结论,您是否已经对各种数字解析技术之间的快乐路径和异常路径进行了性能分析比较,还是只是假设?

但考虑到上下文,并非.NET中的所有解析都将使用TryParse完成。例如,如果数据来自可以信任的已知系统,那么无效格式将是真正的例外,因此我们将其视为这样。但是,如果我们正在处理用户输入,那么无效输入将是更常规的事件,我们希望对此进行相应处理。我们不会通过执行异常处理来做到这一点,我们只会验证并重新提示。

@AnthonyPegram,我什么都没要求,我完全没有C#经验,但是从我对Java和C ++的一点了解以及代码(我认为我认为它具有非凡的品质)来看,我还没有看到了避免例外的情况,因为它们是"昂贵的"。异常被滥用,但使用得当,它比运行正则表达式先检查更便宜(?)当然上下文很重要,但是如果您正在验证用户输入,那么让我告诉您,异常的"成本"是多少?有例外吗?

@Nim,可以追溯到第二部分。如果Im验证用户输入,则Im不会让异常驱动我的决策。多数民众赞成在例外情况的控制流,并在.NET中的不良编程习惯。同样,如果您在没有这种方法的环境中,请使用现有的工具。在.NET中,我们具有TryParse及其快速,功能强大的功能,并且完全适合其典型用法。您的环境可能会有所不同,就像Java很明显一样。

我认为它可以帮助您单击此处。

我能想到的最简单的事情是java.util.Scanner。但是,此方法需要为每个字符串提供一个新的Scanner实例。

String data = ...;

Scanner n = new Scanner(data);

if(n.hasNextInt()){//check if the next chars are integer

int i = n.nextInt();

}else{

}

接下来,您可以编写一个正则表达式模式,该模式用于检查String(复杂的值失败),然后在对字符串进行检查后调用Integer.parseInt()。

Pattern p = Pattern.compile("insert regex to test string here");

String data = ...;

Matcher m = p.matcher(data);

//warning depending on regex used this may

//only check part of the string

if(m.matches()){

int i = Integer.parseInt(data);

}

但是,这两个方法都将字符串解析两次,一次是测试字符串,第二次是获取值。根据获取无效字符串的频率而定,捕获异常可能会更快。

而正则表达式为"(((-| \ +)?[0-9] +(\。[0-9] +)?)+)"

很抱歉,但是我认为正则表达式检查方法比简单地捕获解析异常要慢,对我来说似乎是过早的优化。

@Nim多数民众赞成这就是为什么我写最后一句话,最有可能是Java没有try解析的原因,当大多数值有效时,它的解析速度会变慢。

如果将来有人希望为双打提供良好的解决方案,请使用以下正则表达式:^[-+]?[0-9]*\.?[0-9]+$,它不会允许字符串中的其他任何内容都是数字(因此,不要担心上面的代码中的警告注释)

不幸的是,Java中没有这样的方法。 Java中没有out参数,因此编写这样的方法将需要返回一个空Float来指示错误,或者传递一个FloatHolder对象,该对象可以通过该方法进行修改:

public class FloatHolder {

private float value;

public void setValue(float value) {

this.value = value;

}

public float getValue() {

return this.value;

}

}

public static boolean tryParseFloat(String s, FloatHolder holder) {

try {

float value = Float.parseFloat(s);

holder.setValue(value);

}

catch (NumberFormatException e) {

return false;

}

}

我的观点是:避免使用try / catch来解析这些简单的值,但是感谢您的方法

除了自己重新实现parseFloat之外,您将无法执行此操作。如果所有代码都使用tryParseFloat方法,则不必处理异常。只有tryParseFloat可以。

您不能使用Float吗? (我的Java有点生锈)-FloatHolder怎么了?

您可以使用Float并返回null来指示错误。我在回答中建议了它。 FloatHolder是一种具有类似于C#的TryParse方法的签名的方法。

这是一个古老的问题,但是由于所有答案都没有提及此问题(直到我自己在同事提出的合并请求中看到它之前,我自己才意识到这一点),所以我想向潜在读者介绍番石榴Floats和Ints类:

在这些类的帮助下,您可以编写如下代码:

Integer i = Ints.tryParse("10");

Integer j = Ints.tryParse("invalid");

Float f = Floats.tryParse("10.1");

Float g = Floats.tryParse("invalid.value");

如果值是无效的int或float,则结果将为null,然后您可以按照自己喜欢的任何方式对其进行处理。 (请注意不要将其强制转换为int / float,因为如果该值是无效的整数/浮点值,则会触发NullPointerException。)

请注意,这些方法被标记为" beta",但无论如何它们还是很有用的,我们在生产中使用它们。

作为参考,以下是这些类的Javadocs:

https://google.github.io/guava/releases/snapshot-jre/api/docs/com/google/common/primitives/Ints.html

https://google.github.io/guava/releases/snapshot-jre/api/docs/com/google/common/primitives/Floats.html

Java没有提供内置的tryParse类型的方法,您可以尝试的解决方案之一是创建自己的tryParse方法并将try / catch代码放入此方法中,然后您可以轻松地在整个应用程序中轻松使用此方法,而无需在使用该方法的所有地方都使用try / catch。

示例函数之一可以具有以下代码

public static Long parseLong(String value) {

if(isNullOrEmpty(value)) {

return null;

}

try {

return Long.valueOf(value);

}

catch (NumberFormatException e) {

}

return null;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值