当前位置: 首页 > news >正文

org.apache.commons.lang.math.NumberUtils#isNumber 解释

源码

/*** <p>Checks whether the String a valid Java number.</p>** <p>Valid numbers include hexadecimal marked with the <code>0x</code>* qualifier, scientific notation and numbers marked with a type* qualifier (e.g. 123L).</p>** <p><code>Null</code> and empty String will return* <code>false</code>.</p>** @param str  the <code>String</code> to check* @return <code>true</code> if the string is a correctly formatted number*/public static boolean isNumber(String str) {if (StringUtils.isEmpty(str)) {return false;}char[] chars = str.toCharArray();int sz = chars.length;boolean hasExp = false;boolean hasDecPoint = false;boolean allowSigns = false;boolean foundDigit = false;// deal with any possible sign up frontint start = (chars[0] == '-') ? 1 : 0;if (sz > start + 1) {if (chars[start] == '0' && chars[start + 1] == 'x') {int i = start + 2;if (i == sz) {return false; // str == "0x"}// checking hex (it can't be anything else)for (; i < chars.length; i++) {if ((chars[i] < '0' || chars[i] > '9')&& (chars[i] < 'a' || chars[i] > 'f')&& (chars[i] < 'A' || chars[i] > 'F')) {return false;}}return true;}}sz--; // don't want to loop to the last char, check it afterwords// for type qualifiersint i = start;// loop to the next to last char or to the last char if we need another digit to// make a valid number (e.g. chars[0..5] = "1234E")while (i < sz || (i < sz + 1 && allowSigns && !foundDigit)) {if (chars[i] >= '0' && chars[i] <= '9') {foundDigit = true;allowSigns = false;} else if (chars[i] == '.') {if (hasDecPoint || hasExp) {// two decimal points or dec in exponent   return false;}hasDecPoint = true;} else if (chars[i] == 'e' || chars[i] == 'E') {// we've already taken care of hex.if (hasExp) {// two E'sreturn false;}if (!foundDigit) {return false;}hasExp = true;allowSigns = true;} else if (chars[i] == '+' || chars[i] == '-') {if (!allowSigns) {return false;}allowSigns = false;foundDigit = false; // we need a digit after the E} else {return false;}i++;}if (i < chars.length) {if (chars[i] >= '0' && chars[i] <= '9') {// no type qualifier, OKreturn true;}if (chars[i] == 'e' || chars[i] == 'E') {// can't have an E at the last bytereturn false;}if (chars[i] == '.') {if (hasDecPoint || hasExp) {// two decimal points or dec in exponentreturn false;}// single trailing decimal point after non-exponent is okreturn foundDigit;}if (!allowSigns&& (chars[i] == 'd'|| chars[i] == 'D'|| chars[i] == 'f'|| chars[i] == 'F')) {return foundDigit;}if (chars[i] == 'l'|| chars[i] == 'L') {// not allowing L with an exponentreturn foundDigit && !hasExp;}// last character is illegalreturn false;}// allowSigns is true iff the val ends in 'E'// found digit it to make sure weird stuff like '.' and '1E-' doesn't passreturn !allowSigns && foundDigit;}

NumberUtils#isNumber 解释

org.apache.commons.lang.math.NumberUtils#isNumber 的作用是检查一个字符串是否可以被解析为一个有效的数字。这包括整数、浮点数、科学计数法表示的数以及十六进制数。下面是对代码的逐步解释:

  1. 初始检查:首先,使用 StringUtils.isEmpty(str) 检查输入字符串是否为空或为 null。如果是,方法返回 false

  2. 处理十六进制数:接下来,代码检查字符串是否以 “0x” 开头,这表明它可能是一个十六进制数。如果是,它将遍历字符串的其余部分,确保每个字符都是有效的十六进制数字(0-9, a-f, A-F)。如果所有字符都有效,方法返回 true

  3. 设置循环变量和条件:代码设置了几个变量来跟踪解析过程中的状态,包括是否发现了指数部分 (hasExp)、是否有小数点 (hasDecPoint)、是否允许符号 (allowSigns)、是否找到了数字 (foundDigit)。循环从字符串的开始(或跳过了负号后的第一个字符)开始,直到字符串的倒数第二个字符,或者在需要另一个数字来形成有效数字时直到最后一个字符。

  4. 循环解析字符:在循环中,代码根据当前字符的类型更新状态变量。如果字符是数字,foundDigit 设置为 trueallowSigns 设置为 false。如果字符是小数点,检查是否已经有小数点或指数部分,如果有,则返回 false。如果字符是 ‘e’ 或 ‘E’,检查是否已经有指数部分或之前没有找到数字,如果是,则返回 false;否则,设置 hasExptrue 并允许后续出现符号。如果字符是 ‘+’ 或 ‘-’,检查是否允许符号,如果不允许,则返回 false;否则,重置 allowSignsfoundDigit

  5. 检查最后一个字符:循环结束后,代码检查字符串的最后一个字符。如果是数字,返回 true。如果是 ‘e’ 或 ‘E’,返回 false,因为不能以指数符号结束。如果是小数点,检查是否已经有小数点或指数部分,如果没有且之前找到了数字,则返回 true。如果是类型限定符(‘d’, ‘D’, ‘f’, ‘F’, ‘l’, ‘L’),根据之前的状态返回相应的结果。

  6. 返回结果:最后,如果没有找到不合法的情况,检查 allowSignsfoundDigit 的状态,如果没有挂起的指数符号且至少找到了一个数字,则返回 true;否则,返回 false

总之,这段代码通过一系列的检查和状态跟踪,来判断一个字符串是否可以被解析为一个有效的数字。

NumberUtils.isNumber 示例

下面是一些使用 NumberUtils.isNumber(String str) 方法的示例,以及每个示例的预期返回结果。这些示例展示了不同类型的字符串输入和该方法如何判断它们是否可以被解析为有效的数字。

NumberUtils.isNumber("123"); // true - 正整数
NumberUtils.isNumber("-123"); // true - 负整数
NumberUtils.isNumber("123.45"); // true - 正浮点数
NumberUtils.isNumber("-123.45"); // true - 负浮点数
NumberUtils.isNumber("0.123"); // true - 小于1的浮点数
NumberUtils.isNumber("-0.123"); // true - 小于0的负浮点数
NumberUtils.isNumber("123E4"); // true - 科学计数法
NumberUtils.isNumber("-123E4"); // true - 负的科学计数法
NumberUtils.isNumber("123.45E-6"); // true - 带小数点的科学计数法
NumberUtils.isNumber("0x1A"); // true - 十六进制数
NumberUtils.isNumber("0x1G"); // false - 无效的十六进制数('G' 不是十六进制字符)
NumberUtils.isNumber("123L"); // true - 长整型
NumberUtils.isNumber("NaN"); // false - 不是有效的数字格式
NumberUtils.isNumber("INF"); // false - 不是有效的数字格式
NumberUtils.isNumber(""); // false - 空字符串
NumberUtils.isNumber(null); // false - null 值

请注意,这些示例假设 NumberUtils.isNumber(String str) 方法的实现与之前讨论的代码逻辑一致。实际的返回结果可能会根据具体实现的细节有所不同。

NumberUtils.isCreatable(str) 和 NumberUtils.isNumber(str) 区别

NumberUtils.isCreatable(String str)NumberUtils.isNumber(String str) 都是 Apache Commons Lang 库中的方法,用于判断一个字符串是否可以解析为一个数字。它们之间的主要区别在于它们对可解析数字的定义和容忍度。

  1. NumberUtils.isNumber(String str)(在Apache Commons Lang 3.4及之前的版本中使用):

    • 这个方法用于判断一个字符串是否可以解析为一个有效的Java数字,包括整数、浮点数、和科学计数法表示的数字。
    • 它不接受十六进制格式的数字字符串。
    • 它对于一些边界情况的处理可能不够严格,例如,对于以多个零开头的字符串可能会返回 true
  2. NumberUtils.isCreatable(String str)(在Apache Commons Lang 3.5及之后的版本中引入):

    • 这个方法提供了一个更全面和严格的方式来判断一个字符串是否可以解析为一个数字。
    • 它接受更广泛的数字格式,包括十六进制、八进制和科学计数法。
    • 它更严格地验证字符串格式,以确保解析的数字是有效的。例如,它会检查十六进制数是否只包含有效的十六进制字符。

简而言之,NumberUtils.isCreatable(String str)NumberUtils.isNumber(String str) 的一个改进和扩展版本,提供了更广泛的数字格式支持和更严格的验证。如果你的项目使用的是 Apache Commons Lang 3.5 或更高版本,建议使用 NumberUtils.isCreatable(String str) 来判断字符串是否可以解析为数字。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Python实践:多种方式实现数字前补零
  • uniapp壁纸项目笔记
  • 前端原生Js批量修改页面元素属性的2个方法
  • SprinBoot+Vue在线商城微信小程序的设计与实现
  • 数据库系统 第36节 数据库镜像
  • 【网络安全】XSS(新)+Amazon账户劫持复现
  • 【软件设计】常用设计模式--概述
  • 无人机+应用综合实训室解决方案
  • Linux教程8:文本编辑命令vi
  • 哪款宠物空气净化器能更好的清理浮毛?希喂、352、IAM测评分享
  • 「Python程序设计」循环控制:for和while循环语句
  • SQL进阶技巧:如何查询最近一笔有效订单? | 近距离有效匹配问题
  • 进程间通信方式(共享内存、信号灯集、消息队列)
  • 【重学 MySQL】五、MySQL 的卸载
  • C++——类与对象(一)
  • Java面向对象及其三大特征
  • js中forEach回调同异步问题
  • mongodb--安装和初步使用教程
  • Object.assign方法不能实现深复制
  • php的插入排序,通过双层for循环
  • Python3爬取英雄联盟英雄皮肤大图
  • 技术胖1-4季视频复习— (看视频笔记)
  • 力扣(LeetCode)22
  • 线上 python http server profile 实践
  • 3月7日云栖精选夜读 | RSA 2019安全大会:企业资产管理成行业新风向标,云上安全占绝对优势 ...
  • Spring第一个helloWorld
  • 好程序员大数据教程Hadoop全分布安装(非HA)
  • ​1:1公有云能力整体输出,腾讯云“七剑”下云端
  • ​二进制运算符:(与运算)、|(或运算)、~(取反运算)、^(异或运算)、位移运算符​
  • ​你们这样子,耽误我的工作进度怎么办?
  • #、%和$符号在OGNL表达式中经常出现
  • #java学习笔记(面向对象)----(未完结)
  • (23)Linux的软硬连接
  • (C#)if (this == null)?你在逗我,this 怎么可能为 null!用 IL 编译和反编译看穿一切
  • (LNMP) How To Install Linux, nginx, MySQL, PHP
  • (博弈 sg入门)kiki's game -- hdu -- 2147
  • (十) 初识 Docker file
  • (五)c52学习之旅-静态数码管
  • (原)本想说脏话,奈何已放下
  • (原創) 如何優化ThinkPad X61開機速度? (NB) (ThinkPad) (X61) (OS) (Windows)
  • (转)Android学习系列(31)--App自动化之使用Ant编译项目多渠道打包
  • (转)大型网站的系统架构
  • ****** 二十三 ******、软设笔记【数据库】-数据操作-常用关系操作、关系运算
  • **python多态
  • .NET 6 在已知拓扑路径的情况下使用 Dijkstra,A*算法搜索最短路径
  • .NET MVC第三章、三种传值方式
  • .net 连接达梦数据库开发环境部署
  • .net反混淆脱壳工具de4dot的使用
  • .NET微信公众号开发-2.0创建自定义菜单
  • .net中的Queue和Stack
  • /usr/local/nginx/logs/nginx.pid failed (2: No such file or directory)
  • [100天算法】-目标和(day 79)
  • [ABC275A] Find Takahashi 题解
  • [AI 大模型] 百度 文心一言
  • [BZOJ1008][HNOI2008]越狱