将字符串表示转换为最小数字对象

时间:2016-09-13 06:05:15

标签: java

有一个数字的字符串表示(无小数),将它转换为java.lang.Integerjava.lang.Longjava.math.BigInteger之一的最佳方法是什么?唯一的条件是转换后的类型应该是保存数字所需的最小数据类型。

我这个当前的实现工作正常,但我想知道是否有更好的代码而没有异常处理。

package com.stackoverflow.programmer;

import java.math.BigInteger;

public class Test {
    public static void main(String[] args) {

        String number = "-12121111111111111";
        Number numberObject = null;
        try {
            numberObject = Integer.valueOf(number);
        } catch (NumberFormatException nfe) {
            System.out.println("Number will not fit into Integer type. Trying Long...");
            try {
                numberObject = Long.valueOf(number);
            } catch (NumberFormatException nfeb) {
                System.out.println("Number will not fit into Long type. Trying BigInteger...");
                numberObject = new BigInteger(number);
            }
        }
        System.out.println(numberObject.getClass() + " : "
                + numberObject.toString());
    }
}

3 个答案:

答案 0 :(得分:4)

根据你的说法,这就是我要做的事情:

<input name="q1" type="radio" value="A" onchange="showStuff('A', this); return false;" />
<input name="q1" type="radio" value="B" onchange="showStuff('B', this); return false;" />

<div id="A" style="display:none">
  This should display only when A button is clicked
</div>
<div id="B" style="display:none">
  This should display only when B button is clicked
</div>

你必须使用一个临时的BigInteger,否则你最终会得到lazarov的解决方案,这是正确的,但是由于评论中提到的原因,你无法真正做到这一点。

无论如何,每个BigInteger(未返回的)都将被垃圾收集。至于自动装箱,我不认为这是一件坏事。你也可以制作&#34; import java.math.BigInteger; import java.util.Arrays; import java.util.List; public class TestSO09_39463168_StringToMinimalNumber { public static void main(String[] args) { List<String> strNumbers = Arrays.asList("0", //int "123", //int "-456", //int "2147483700", // Long "-2147483700", // Long "9223372036854775900", //BigInt "-9223372036854775900" //BigInt ); for(String strNumber : strNumbers){ Number number = stringToMinimalNumber(strNumber); System.out.println("The string '"+strNumber+"' is a "+number.getClass()); } } public static Number stringToMinimalNumber(String s){ BigInteger tempNumber = new BigInteger(s); if(tempNumber.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) > 0 || tempNumber.compareTo(BigInteger.valueOf(Long.MIN_VALUE)) < 0){ return tempNumber; } else if(tempNumber.compareTo(BigInteger.valueOf(Integer.MAX_VALUE)) > 0 || tempNumber.compareTo(BigInteger.valueOf(Integer.MIN_VALUE)) < 0){ return tempNumber.longValue(); //Autobox to Long } else { return tempNumber.intValue(); //Autobox to Integer } } } &#34;作为常数。也许编译器或JVM会自己完成这个。

我不确定它的效率如何,仅使用BigInteger可能是一个好主意(正如Spotted所做的那样),因为我严重怀疑它会真正改善你的其余代码以使用正确的大小如果你试图将这些数字相互使用,它甚至可能容易出错......但同样,这一切都取决于你需要什么。 (是的,使用Exception作为流控制是一个非常糟糕的主意,但如果BigInteger.valueOf(Long.MAX_VALUE))根本不是数字,你可以在BigInteger tempNumber = new BigInteger(s);上添加try catch以抛出自己的异常

为了娱乐目的,我在不使用BigInteger的情况下制作了解决方案,并且只使用String解析(这仍然不是我建议做的,但很有趣:)

s

答案 1 :(得分:1)

请不要使用异常来处理流量控制,这是serious anti-pattern(也是here)。

正如您在评论中提到的,您被问到的真实事情是将List<String>转换为List<Number>。 另外,如果我理解正确,你知道:

  • 您应该只遇到没有小数的数字
  • 您可能遇到的最大值可能是未绑定的

基于此,以下方法将以更聪明的方式完成工作:

private static List<Number> toNumbers(List<String> strings) {
    return strings.stream()
                  .map(BigInteger::new)
                  .collect(Collectors.toList());
}

Eidt:如果您对流概念不是很熟悉,那么这里是没有流的等效代码:

private static List<Number> toNumbers(List<String> strings) {
    List<Number> numbers = new ArrayList<>();
    for (String s : strings) {
        numbers.add(new BigInteger(s));
    }
    return numbers;
}

答案 2 :(得分:0)

好吧,如果你想这样做&#34;手工&#34;尝试这样的事情:

我们将最大值定义为字符串:

String intMax = "2147483647";
String longMax = "9223372036854775807";

和我们的号码:

String ourNumber = "1234567890"

现在我们的逻辑很简单: 我们将首先检查字符串的长度

  1. 如果我们的数字长度&lt; int max length:IT IS INT

  2. 如果我们的数字长度== int最大长度:检查是INT还是LONG

  3. 如果我们的数字长度> int max length:

    3.1如果我们的数字长度&lt;长最大长度:它很长

    3.2如果我们的数字长度==长最大长度:检查是LONG还是BIG INTEGER

    3.3如果我们的数字长度>长最大长度:它是大整数

  4. 代码应该看起来像这样(我没有尝试编译它可能有语法或其他错误):

    if(ourNumber.lenght() < intMax.length ){
        System.out.println("It is an Integer");
    } else if(ourNumber.lenght() == intMax.length){
        // it can be int if the number is between 2000000000 and 2147483647
                char[] ourNumberToCharArray = ourNumber.toCharArray();
                char[] intMaxToCharArray = intMax.toCharArray();
                int diff = 0;
                for(int i = 0; i < ourNumberToCharArray.length; i++) {  
                    diff  = Character.getNumericValue(intMaxToCharArray[i]) - Character.getNumericValue(ourNumberToCharArray[i]);
                    if(diff > 0) { 
                        System.out.println("It is a Long");
                        break;                  
                    } else if(diff < 0) {
                        System.out.println("It is an Integer");
                            break;
                    }
                }
                if(diff == 0){
                  System.out.println("It is an Integer");  
                }   
    } else { 
        if(ourNumber.lenght() < longMax.length()) {
            System.out.println("It is a Long");
        } else if(ourNumber.lenght() == longMax.length()){
                char[] ourNumberToCharArray = ourNumber.toCharArray();
                char[] longMaxToCharArray = longMax.toCharArray();
                int diff = 0;
                for(int i = 0; i < ourNumberToCharArray.length; i++) {  
                    diff  = Character.getNumericValue(longMaxToCharArray[i]) - Character.getNumericValue(ourNumberToCharArray[i]);
                    if(diff > 0) { 
                        System.out.println("It is a BigInteger");
                        break;                  
                    } else if(diff < 0) {
                        System.out.println("It is a Long");
                            break;
                    }
                }   
                if(diff == 0){
                  System.out.println("It is a Long");  
                }   
        } else { 
            System.out.println("It is a BigInteger");
        }
    }
    

    然后检查数字是否匹配的逻辑在两种情况下都是相同的,但是它在一个函数中就可以了。例如。