This is the 25th day of my participation in the August Genwen Challenge.More challenges in August

The article directories

  • Understand packaging categories
  • Integer
  • Double
  • BigDecimal
  • BigInteger

Understand packaging categories

Eight basic data types are predefined in Java, including: byte, int, Long, Double, float, Boolean, char, and short. The biggest difference between primitive types and object types is that primitive types are based on values and object types are based on references.

For example, there is a method f() that takes object type and primitive type:

void f(Object obj){
	// Parameter reference type, which holds the memory address
}

f(123) {// Basic type
}
Copy the code

Primitive types are numeric based, so there is no class for primitive types. There is no concept of a class. That is, variables can only store values, but they do not have methods to manipulate data.

Object types are completely different. A variable is actually an instance of a class. It can have information such as attribute methods.

What “wrapper types” are provided in Java to compensate for the lack of object-oriented thinking of “primitive types”? See the table below:

Basic types of Packing type
byte Byte
short Short
int Integer
long Long
float Float
double Double
char Character
boolean Boolean

java.lang.Number

Java.lang. Number is the parent of all numeric classes, and its direct subclasses include Byte, Short, Integer, Long, Float, Double, BigDecimal, and BigInteger.

The methods used by these classes to retrieve internally encapsulated primitives are simple and easy to remember: byteValue(), shortValue(), intValue(), longValue(), floatValue(), doubleValue()

The other uses are basically the same, so let’s take Integer and Double as examples

Integer

The first thing to be clear about is that since Integer is a wrapper for int, it must be possible to store Integer values just like int. Interested students can look at the source code.

The Integer class defines a private field value that holds an Integer value. The wrapper class encapsulates various operations around this value:

Create an object

Integer i1 = 21;
Integer i2 = Integer.valueOf("21");
Copy the code

Automatic unpacking The so-called “unpacking” refers to the process that the packaging type is converted to the basic type, and the so-called “packing” is the process that the basic type is converted to the packaging type.

Integer integer = new Integer(21);/ / packing
int num = integer.intValue();/ / split open a case
Copy the code

Since the introduction of auto-unboxing in JDK1.5, the above code can be simplified as follows:

Integer integer = 21;/ / packing
int num = integer;/ / split open a case
Copy the code

So let’s analyze it.

Automatic packing Integer Integer = 21; An object of type Integer cannot be assigned a primitive value directly. An Integer holds a memory address. 21 automatically encapsulates an object and assigns the address of this object to integer. This object is automatically created and automatically boxed. Integer Integer = integer.valueof (21);

Int num = integer; Define a variable of type int. Num should store a value directly. Integer holds a memory address. Integer automatically fetches the value from the object and assigns the value to NUM. Int num = integer.intValue();

Unboxing requires method calls and consumes resources, so we should try to avoid a lot of unboxing operations in our programs.

Be careful of null values for automatic unpacking

Let’s look at the following procedure:

public class Main {
    public static void main(String[] args) {
        int j = 0;
        List<Integer> list = new ArrayList<>();
        list.add(3);
        list.add(null);
        for (inti : list) { j += i; } System.out.println(j); }}Copy the code

A null pointer is reported at runtime



So when the value may be empty to box, must be added to the null value of the check. So you can change the program to:



The program results are as follows:

3

The interview questions 1

		Integer i1 = 100;
        Integer i2 = 100;
        Integer i3 = 200;
        Integer i4 = 200;

        System.out.println(i1==i2);
        System.out.println(i3==i4);
Copy the code

Output result:

true
false
Copy the code

The Integer class contains an Integer instance cache array ranging from -128-127. If the int value given to the local variable is in the range above when autoboxing, if it is in the range, use the existing cache object; If the value is not in the range, the new object is created.

The interview questions 2

		Integer i1 = new Integer(21);
        Integer i2 = new Integer(21);
        System.out.println(i1 == i2);
        System.out.println(i1.equals(i2));
Copy the code

Output result:

false
true
Copy the code

If new creates space in the heap, it creates two Spaces twice, and the addresses of the two Spaces must be different. I don’t recommend it. It’s out of date.

ByteValue (), shortValue(), intValue(), longValue(), floatValue(), doubleValue()

Int integer.parseint (“255”); ParseInt (“11111111”, 2); parseInt(“377”,8); parseInt(“377”,8); ParseInt (“ff”, 16); Integer. ToBinaryString (255); // Convert the number to binary and parse it into “11111111” integer.tooctalString (255); // Convert digits to octal and parse to “377” integer.tohexString (255); // Convert the number to hexadecimal and parse to “ff”

Complete the program

		System.out.println("i1:" + Integer.parseInt("255"));
        System.out.println("i2:" + Integer.parseInt("11111111".2));
        System.out.println("i3:" + Integer.parseInt("377".8));
        System.out.println("i4:" + Integer.parseInt("ff".16));

        System.out.println("s1:" + Integer.toBinaryString(255));
        System.out.println("s2:" + Integer.toOctalString(255));
        System.out.println("s3:" + Integer.toHexString(255));
Copy the code

The output

255
255
255
255
11111111
377
ff
Copy the code

Double

The Double class wraps the value of a primitive type Double in an object. An object of class Double contains a field of type Double. In addition, the class provides methods to convert double to String, as well as constants and methods that are commonly used when working with double.

Create an object

Double d1 = 21d;
Double d2 = Double.valueOf("21");
Copy the code

methods

Double. ParseDouble (“3.14”); Double(“3.14”); Double. IsInfinite (Double d) : returns true if the value represented by this object is positive or negative infinity; IsNaN (Double d) : True if this Double value is a non-numeric value, false otherwise

NaN: Not a number

BigDecimal

Floating-point operations are imprecise. Let’s look at the following operations

System.out.println(2 - 1.9);
System.out.println(4.35 * 100);
Copy the code

Operation results:



So why does this happen?

Because both floats and doubles are floating-point numbers, and computers are binary, floating-point numbers lose some precision. The root cause is that decimal values usually do not have exactly the same binary representation, and the binary representation of decimal numbers can be imprecise. You can only get infinitely close to that value.

The purpose of BigDecimal is to do precise floating-point arithmetic

A constructor

public BigDecimal(double val)doubleRepresentation conversion to BigDecimal * is not recommendedpublic BigDecimal(int val)willintThe representation is converted to BigDecimalpublic BigDecimal(String val)Converting the String representation to BigDecimal * is recommendedCopy the code

The results of constructors with arguments of type double are somewhat unpredictable. So it’s usually not used.

The String constructor is completely predictable: writing newBigDecimal(” 0.1 “) creates a BigDecimal that is exactly equal to the expected 0.1. Therefore, it is generally recommended to use the String constructor in preference.

When double must be used as a source for BigDecimal, convert toString using double.tostring (double) and then use the String constructor. Or use BigDecimal’s static method, valueOf.

Bd1 shows the unpredictability of the double constructor, DB2 shows the String constructor, and Bd3 and Bd4 show the correct double constructor.

		BigDecimal bd1 = new BigDecimal(1.9);
        BigDecimal bd2 = new BigDecimal("1.9");
        BigDecimal bd3 = BigDecimal.valueOf(1.9);
        BigDecimal bd4 = new BigDecimal(Double.toString(1.9));


        System.out.println("db1:" + bd1);
        System.out.println("db2:" + bd2);
        System.out.println("db3:" + bd3);
        System.out.println("db4:" + bd4);
Copy the code

Running results:

Subtract (BigDecimal BD)+ Subtract (BigDecimal BD) -multiply (BigDecimal BD)* divide(BigDecimal BD)/ divide(BigDecimal (bd, reserved digits, rounded) setScale(reserved digits, rounded) round operation, the result of the operation is returned as a new large number object

Example: Implement the exact calculation at the beginning of this section

		BigDecimal bd1 = new BigDecimal("2");
        BigDecimal bd2 = new BigDecimal("1.9");
        System.out.println("2-1.9 =" + bd1.subtract(bd2));

        BigDecimal bd3 = new BigDecimal("4.35");
        BigDecimal bd4 = new BigDecimal("100");
        System.out.println("4.35 * 100 =" + bd3.multiply(bd4));
Copy the code

Running results:



Example: Round

BigDecimal bd = BigDecimal.valueOf(2.345);
double result = bd.setScale(2, RoundingMode.HALF_UP).doubleValue();
System.out.println("result:" + result);
Copy the code

Running results:



Example: Calculate the landing distance

		System.out.println("Enter time of descent.");
        double t = new Scanner(System.in).nextDouble();
        / / 1/2 * 9.8 * t * t
        BigDecimal a = BigDecimal.valueOf(0.5);
        BigDecimal b = BigDecimal.valueOf(9.8);
        BigDecimal c = BigDecimal.valueOf(t);

        double result = a.multiply(b).multiply(c.pow(2)).doubleValue();

        System.out.println("Landing distance:" + result + "米");
Copy the code

Running results:

BigInteger

Purpose: To do large integer arithmetic

In Java, the maximum range of integral types natively provided by the CPU is a 64-bit long integer. Long integers can be computed directly from CPU instructions, which is very fast.

What if we use a range of integers beyond long? At this point, software can only simulate a large integer. Java.math. BigInteger is used to represent integers of any size.

We can see its use with an example.

Example: Calculating factorials

public class Main {
    public static void main(String[] args) {
        System.out.println("Enter a number to compute the factorial:");
        int number = new Scanner(System.in).nextInt();
        System.out.println("Factorial result:" + f(number));
    }

    private static String f(int number) {
        // Large integer arithmetic
        BigInteger bd = BigInteger.valueOf(number);
        for (int i = number - 1; i >= 1; i--) {
            BigInteger bi = BigInteger.valueOf(i);
            bd = bd.multiply(bi);
        }
        returnbd.toString(); }}Copy the code

Running results:



methods

BigInteger abs(a)Returns the absolute value of a large integer, BigIntegeradd(BigInteger val)Returns the sum of two large integersand(BigInteger val)Returns the result of the bitwise sum of two large integers, BigIntegerandNot(BigInteger val)Returns the result of two large integers and not BigIntegerdivide(BigInteger val)Returns the quotient of two large integersdouble doubleValue(a)Of a large integerdoubleThe value of the typefloat floatValue(a)Of a large integerfloatThe value of type BigIntegergcd(BigInteger val)Returns the greatest common divisor of a large integerint intValue(a)Returns the integer value of a large integerlong longValue(a)Of a large integerlongValue type BigIntegermax(BigInteger val)Returns the largest BigInteger of two large integersmin(BigInteger val)Returns the smallest of two large integers, BigIntegermod(BigInteger val)Modulo val with the current BigIntegermultiply(BigInteger val)Returns the product of two large integers, BigIntegernegate(a)Returns the negative of the current large integer, BigIntegernot(a)Returns a non-bigINTEGER for the current large integeror(BigInteger val)Returns the bitwise or BigInteger of two large integerspow(int exponent)Returns the exponent BigInteger of the current large integerremainder(BigInteger val)Returns the remainder of the current large integer divided by val, BigIntegerleftShift(int n)Returns BigInteger after shifting the current large integer n bits to the leftrightShift(int n)Returns BigInteger after shifting the current large integer n bits to the rightsubtract(BigInteger val)Returns the result of subtracting two large integersbyte[] toByteArray(BigInteger val)Convert large integers to binary inverse and save it inbyteThe String in the arraytoString(a)Converts the current large integer to the decimal string form BigIntegerxor(BigInteger val)Returns xOR of two large integersCopy the code

Refer to basic data types and their wrapper classes (I) for Java BigDecimal details