Статьи

Новые методы BigInteger в Java 8

Внимание к новым функциям в JDK 8 по праву сфокусировано на новых функциях и синтаксисе языка. Тем не менее, есть несколько приятных дополнений к библиотекам и API, и в этой статье я расскажу о четырех новых методах, добавленных в класс BigInteger : longValueExact () , intValueExact () , shortValueExact () и byteValueExact () .

Все четыре недавно представленных метода «xxxxxExact ()» генерируют исключение ArithmeticException, если число, содержащееся в экземпляре BigInteger не может быть предоставлено в указанной форме (указанной в имени метода) без потери информации. BigInteger уже имеет методы intValue () и longValue (), а также унаследованные (от Number) методы shortValue () и byteValue () . Эти методы не генерируют исключения, если значение BigInteger теряет информацию в представлении как один из этих типов. Хотя на первый взгляд это может показаться преимуществом, это означает, что код, использующий результаты этих методов, использует значения, которые не являются точными без какой-либо возможности узнать, что информация была потеряна. Новые методы «xxxxxExact» генерируют ArithmenticException а не ArithmenticException вид, что предоставляют результат, который потерял значительную информацию.

В следующем простом листинге кода демонстрируются «устаревшие» методы, которые представляют неправильные данные в типах byte , short , int и long а не выдают исключение. В том же коде также демонстрируется использование новых методов «xxxxxExact», которые выдают исключение при потере информации, а не представляют неверное представление. Результат выполнения этого кода следует за кодом и демонстрирует, как методы ведут себя по-разному, когда BigInteger содержит значение с большей информацией, чем может представлять возвращаемый byte , short , int или long .

BigIntegerDem.java

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
package dustin.examples.jdk8;
 
import static java.lang.System.out;
import java.math.BigInteger;
 
/**
 * Demonstrate the four new methods of BigInteger introduced with JDK 8.
 *
 * @author Dustin
 */
public class BigIntegerDemo
{
   /**
    * Demonstrate BigInteger.byteValueExact().
    */
   private static void demonstrateBigIntegerByteValueExact()
   {
      final BigInteger byteMax = new BigInteger(String.valueOf(Byte.MAX_VALUE));
      out.println("Byte Max: " + byteMax.byteValue());
      out.println("Byte Max: " + byteMax.byteValueExact());
      final BigInteger bytePlus = byteMax.add(BigInteger.ONE);
      out.println("Byte Max + 1: " + bytePlus.byteValue());
      out.println("Byte Max + 1: " + bytePlus.byteValueExact());
   }
 
   /**
    * Demonstrate BigInteger.shortValueExact().
    */
   private static void demonstrateBigIntegerShortValueExact()
   {
      final BigInteger shortMax = new BigInteger(String.valueOf(Short.MAX_VALUE));
      out.println("Short Max: " + shortMax.shortValue());
      out.println("Short Max: " + shortMax.shortValueExact());
      final BigInteger shortPlus = shortMax.add(BigInteger.ONE);
      out.println("Short Max + 1: " + shortPlus.shortValue());
      out.println("Short Max + 1: " + shortPlus.shortValueExact());
   }
 
   /**
    * Demonstrate BigInteger.intValueExact().
    */
   private static void demonstrateBigIntegerIntValueExact()
   {
      final BigInteger intMax = new BigInteger(String.valueOf(Integer.MAX_VALUE));
      out.println("Int Max: " + intMax.intValue());
      out.println("Int Max: " + intMax.intValueExact());
      final BigInteger intPlus = intMax.add(BigInteger.ONE);
      out.println("Int Max + 1: " + intPlus.intValue());
      out.println("Int Max + 1: " + intPlus.intValueExact());
   }
 
   /**
    * Demonstrate BigInteger.longValueExact().
    */
   private static void demonstrateBigIntegerLongValueExact()
   {
      final BigInteger longMax = new BigInteger(String.valueOf(Long.MAX_VALUE));
      out.println("Long Max: " + longMax.longValue());
      out.println("Long Max: " + longMax.longValueExact());
      final BigInteger longPlus = longMax.add(BigInteger.ONE);
      out.println("Long Max + 1: " + longPlus.longValue());
      out.println("Long Max + 1: " + longPlus.longValueExact());
   }
 
   /**
    * Demonstrate BigInteger's four new methods added with JDK 8.
    *
    * @param arguments Command line arguments.
    */
   public static void main(final String[] arguments)
   {
      System.setErr(out); // exception stack traces to go to standard output
      try
      {
         demonstrateBigIntegerByteValueExact();
      }
      catch (Exception exception)
      {
         exception.printStackTrace();
      }
 
      try
      {
         demonstrateBigIntegerShortValueExact();
      }
      catch (Exception exception)
      {
         exception.printStackTrace();
      }
 
      try
      {
         demonstrateBigIntegerIntValueExact();
      }
      catch (Exception exception)
      {
         exception.printStackTrace();
      }
 
      try
      {
         demonstrateBigIntegerLongValueExact();
      }
      catch (Exception exception)
      {
         exception.printStackTrace();
      }
   }
}

Выход

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
Byte Max: 127
Byte Max: 127
Byte Max + 1: -128
java.lang.ArithmeticException: BigInteger out of byte range
 at java.math.BigInteger.byteValueExact(BigInteger.java:4428)
 at dustin.examples.jdk8.BigIntegerDemo.demonstrateBigIntegerByteValueExact(BigIntegerDemo.java:23)
 at dustin.examples.jdk8.BigIntegerDemo.main(BigIntegerDemo.java:75)
Short Max: 32767
Short Max: 32767
Short Max + 1: -32768
java.lang.ArithmeticException: BigInteger out of short range
 at java.math.BigInteger.shortValueExact(BigInteger.java:4407)
 at dustin.examples.jdk8.BigIntegerDemo.demonstrateBigIntegerShortValueExact(BigIntegerDemo.java:36)
 at dustin.examples.jdk8.BigIntegerDemo.main(BigIntegerDemo.java:84)
Int Max: 2147483647
Int Max: 2147483647
Int Max + 1: -2147483648
java.lang.ArithmeticException: BigInteger out of int range
 at java.math.BigInteger.intValueExact(BigInteger.java:4386)
 at dustin.examples.jdk8.BigIntegerDemo.demonstrateBigIntegerIntValueExact(BigIntegerDemo.java:49)
 at dustin.examples.jdk8.BigIntegerDemo.main(BigIntegerDemo.java:93)
Long Max: 9223372036854775807
Long Max: 9223372036854775807
Long Max + 1: -9223372036854775808
java.lang.ArithmeticException: BigInteger out of long range
 at java.math.BigInteger.longValueExact(BigInteger.java:4367)
 at dustin.examples.jdk8.BigIntegerDemo.demonstrateBigIntegerLongValueExact(BigIntegerDemo.java:62)
 at dustin.examples.jdk8.BigIntegerDemo.main(BigIntegerDemo.java:102)

Как показывает вышеприведенный вывод, новые методы BigInteger с «xxxxxExact» в имени не будут представлять неточные представления, когда возвращаемый тип не может содержать информацию в экземпляре BigInteger . Хотя исключения, как правило, не являются нашей любимой вещью, они почти всегда будут лучше, чем получение и использование неправильных данных, и даже не осознавать, что это неправильно.

Ссылка: Новые методы BigInteger в Java 8 от нашего партнера JCG Дастина Маркса из блога Inspired by Actual Events .