【问题标题】:How to determine the type of primitive in a String representation?如何确定字符串表示中的基元类型?
【发布时间】:2023-03-29 07:57:01
【问题描述】:


我有一个原语的字符串表示,我的目标是确定它是哪个原语。
我的功能如下:

public Object getPrimitive(String primitiveAsString) {
.....
}

例如,如果输入是“223”,我想返回一个整数,但如果输入是“223.1”甚至是“223.0”(!!),则返回一个双精度数。此外,我想区分浮点数和双精度数,甚至整数和“BigInteger”。

我尝试了使用 NumberFormat 的解决方案,但它对我不起作用....

有没有一种优雅的方法可以做到这一点?

谢谢!

【问题讨论】:

  • 不,没有优雅的方法。
  • 您需要支持哪些原始类型?
  • 如何区分整数的String表示和BigInteger的表示(只要值在MAX_INT和MIN_INT之间)?
  • BigInteger 不是原语。同样,让方法返回object 是没有意义的,而方法的名称是getPrimitive
  • 而原因(对于那些问过的人)是初始化一个 Map 稍后将由 Gson.toJson(myMap) 解析,结果将发送给客户端.

标签: java primitive number-formatting


【解决方案1】:

一个想法只是尝试在 try-catch 中返回每种类型。

代码:(错误检查可能不太理想)

public static void main(String[] args)
{
    System.out.println(getPrimitive("123")); // Byte
    System.out.println(getPrimitive("1233")); // Short
    System.out.println(getPrimitive("1233587")); // Integer
    System.out.println(getPrimitive("123.2")); // Float
    System.out.println(getPrimitive("123.999999")); // Double
    System.out.println(getPrimitive("12399999999999999999999999")); // BigInteger
    System.out.println(getPrimitive("123.999999999999999999999999")); // BigDecimal
}

static public Object getPrimitive(String string)
{
  try { return Byte.valueOf(string);       } catch (Exception e) { };
  try { return Short.valueOf(string);      } catch (Exception e) { };
  try { return Integer.valueOf(string);    } catch (Exception e) { };
  try { return new BigInteger(string);     } catch (Exception e) { };
  try { if (string.matches(".{1,8}"))
          return Float.valueOf(string);    } catch (Exception e) { };
  try { if (string.matches(".{1,17}"))
          return Double.valueOf(string);   } catch (Exception e) { };
  try { return new BigDecimal(string);     } catch (Exception e) { };
  // more stuff ?
  return null;
}

.{1,8}.{1,17} 背后的原因是 floatdouble 分别精确到大约 7 位和 16 位数字(根据一些随机来源)。 . 是通配符。 {x,y} 表示在 x 和 y 之间重复。

编辑:

改进了区分floatdoubleBigDecimal 的基本正则表达式。

【讨论】:

  • 您将如何确定属于 BigInteger/BigDecimal 的数字,因为 Integer.parseInt() 本身会将其正确解析为整数。
  • @Ankur 12399999999999999999999999Integer 大,所以它会落入BigInteger
  • 数量少怎么办?它仍然可以属于 BigInteger
  • @Ankur 我认为 OP 正在寻找一种贪婪的方法 - 如果是 int,则返回,如果是 BigInteger,则返回,如果是 float,则返回,等等。
【解决方案2】:

我怀疑你可以很容易地做到这一点。要检测 String 的内容是属于整数还是 BigInteger 将非常棘手或几乎不可能。您当然可以通过编写正则表达式来区分 int 和 double/float 以确定它是否包含 '.' 并且其余字符是数字。

【讨论】:

    【解决方案3】:

    我会做这样的事情......这应该适用于 BigInteger 和 BigDecimal 以及......虽然还没有测试过。

    public Object getPrimitive(String primitiveAsString) {
        String value = primitiveAsString;
    
        try {
          return Byte.valueOf(value);
        } catch (NumberFormatException ex) { }
    
        try {
          return Short.valueOf(value);
        } catch (NumberFormatException ex) { }
    
        try {
          return Integer.valueOf(value);
        } catch (NumberFormatException ex) { }
    
        try {
          return Float.valueOf(value);
        } catch (NumberFormatException ex) { }
    
        try {
          return Double.valueOf(value);
        } catch (NumberFormatException ex) { }
    
        try {
          return Long.valueOf(value);
        } catch (NumberFormatException ex) { }
    
        try {
          return new BigInteger(value);
        } catch (NumberFormatException ex) { }
    
        try {
          return new BigDecimal(value);
        } catch (NumberFormatException ex) { }
    
        if(value.length() == 1) {
          return new Character(value.charAt(0));
        }
    
        return null;
    }
    

    编辑:改进了解决方案以适应输入为 BigInteger/BigDecimal 的情况。此解决方案不使用任何正则表达式。

    【讨论】:

    • 你的订单错了,ByteShort永远不会触发(因为所有Bytes和Shorts也是Integers。Float也不会触发(被Double)。
    • 尝试找到任何将返回DoubleBigDecimal 的测试用例。 Float 可能会涵盖所有内容(即使它很重)。这就是你需要正则表达式的原因。
    猜你喜欢
    • 2011-01-07
    • 1970-01-01
    • 1970-01-01
    • 2018-05-18
    • 2017-06-13
    • 1970-01-01
    • 1970-01-01
    • 2015-11-01
    • 1970-01-01
    相关资源
    最近更新 更多