Comparison of basic data types

The knowledge of data types is indeed very basic, but if you don’t fully understand it, you may be despised during the interview or a serious bug if you are not careful at work. So take a moment to sort it out.

8 basic data types and corresponding packaging types :
byte, short, int, long, float, double, boolean, char
Byte, Short, Integer, Long, Float, Double, Boolean, Character
About cache range

The four packaging classes Byte, Short, Integer, and Long create cache data of [-128, 127] by default;
Character creates cache data of [0,127] by default;
Boolean directly returns true or false;
Regarding the range of default cache data, the upper limit of 127 can be changed and configured to increase it, but the lower limit of -128 cannot be changed. If it exceeds the corresponding range, a new object will be created, and the cache will not be exceeded directly

The difference between == and equals : The former is to compare the value of the memory address, and the latter is to compare the actual value of the object itself.

Let's look at the comparison code and results. (The rough title is a shorthand outline, the comments in the code are detailed explanations, and the code is an example)

1. The variables on both sides are all of type int are equal. The following results are all true

// 基本类型的比较都是相等(不论赋值方式、即使值做了运算),也不区分是否超出缓存范围
 System.out.println("两边都定义的基本类型变量比较 缓存范围内");
 int a = 10;
 int b = 10;
 int c = 0;
 int d = new Integer(10);
 int e = new Integer(10);
 int f = new Integer(0);
 System.out.println(a==b);
 System.out.println(10==b);
 System.out.println(d==e);
 System.out.println(10==e);
 System.out.println(a==d);
 System.out.println(a==b+c);
 System.out.println(10==b+c);
 System.out.println(d==e+f);
 System.out.println(10==e+f);
 System.out.println("两边都定义的基本类型变量比较 缓存范围外");
 int a1 = 130;
 int b1 = 130;
 int c1 = 0;
 int d1 = new Integer(130);
 int e1 = new Integer(130);
 int f1 = new Integer(0);
 System.out.println(a1==b1);
 System.out.println(130==b1);
 System.out.println(d1==e1);
 System.out.println(130==e1);
 System.out.println(a1==d1);
 System.out.println(a1==b1+c1);
 System.out.println(130==b1+c1);
 System.out.println(d1==e1+f1);
 System.out.println(a1==a1+f1);
 System.out.println(130==a1+f1);

2. The variables on both sides are of wrapping type (direct comparison without calculation) , and within the scope of the non-cache array, regardless of the assignment method, they are not equal, because the memory address values ​​​​of the two new variables beyond the scope of the new object are not equal, and within the scope of the cache, as long as any one of the variables on both sides appears with the new keyword, they are all unequal. To sum up, only Integer g = 10; Integer h = 10 are equal and the value is [-128,127] because the cache is taken and the new one is not created.

System.out.println("两边都定义的包装类型变量比较");
Integer g = 10, i = 130; // 等同 Integer g = Integer.valueOf(10);
Integer h = 10, j = 130, j1 = 0;
Integer l = new Integer(10);
Integer m = new Integer(10);
Integer n = new Integer(130);
Integer o = new Integer(130);
Integer p = new Integer(0);
System.out.println(g==h); // true
System.out.println(i==j); // false 有new关键字出现
System.out.println(i==j); // false 有new关键字出现
System.out.println(l==m); // false 有new关键字出现
System.out.println(n==o); // false 有new关键字出现
System.out.println(g==l); // false 有new关键字出现
System.out.println(i==n); // false 有new关键字出现

3. The variables on both sides are of packaging type (comparison after calculation) are equal , regardless of whether the two variable types used for calculation are consistent. The following results are all true

System.out.println("定义的包装类型变量比较 同时做了运算");
// 缓存内 同种赋值方式、不同赋值方式 的比较
System.out.println(g==h + j1);
System.out.println(g==h + p);
System.out.println(g==l + j1);
System.out.println(g==l + p);
System.out.println(l==g + j1);
System.out.println(l==g + p);
System.out.println(l==m + j1);
System.out.println(l==m + p);
// 缓存外 同种赋值方式、不同赋值方式 的比较
System.out.println(i==j + j1);
System.out.println(i==j + p);
System.out.println(i==n + j1);
System.out.println(i==n + p);
System.out.println(n==j + j1);
System.out.println(n==j + p);
System.out.println(n==o + j1);
System.out.println(n==o + p);

4. The data types of the variables on both sides are inconsistent and compared, and they are all equal (the reason for automatic unboxing and packing)

System.out.println("定义的基本类型与包装类型变量交叉比较");
int q = 10, u = 0;
int r = 130;
Integer s = 10, v = 0;
Integer t = 130;
Integer w = new Integer(10);
Integer x = new Integer(130);
Integer y = new Integer(0);
/** 不做运算 **/
// 缓存内 int 和 Integer
System.out.println(q==s);
System.out.println(q==w);
// 缓存外 int 和 Integer
System.out.println(r==t);
System.out.println(r==x);
/** 做运算 **/
// 缓存内 int 和 Integer
System.out.println(q==s + u);
System.out.println(q==s + v);
System.out.println(q==s + y);
System.out.println(q==w + u);
System.out.println(q==w + v);
System.out.println(q==w + y);
// 缓存外 int 和 Integer
System.out.println(r==t + u);
System.out.println(r==t + v);
System.out.println(r==t + y);
System.out.println(r==x + u);
System.out.println(r==x + v);
System.out.println(r==x + y);

The final summary is as follows

 Int和Int比较,只要数值相等都相等
​ Integer和Integer比较,数值相等时,(-128,127)内的相等,其他的不等。
​ new Integer 和 new Integer比较,都不相等。
​ new Integer 和 Integer比较,都不相等。
​ Int和Integer比较,只要数值相等都相等。

速记口诀:
两边都是int或者两边交叉都是true;
两边都是包装时,只有赋值方式是 "= 数字" 且数字在缓存范围内为true或者两边有一边做了运算为true,其他情况都是false

The comparison of the wrapper type should be converted to int type by equals or the .intValue() method provided by the wrapper class

Regarding the string type , see the following code

String s1 = "zhangsan";
String s2 = "zhangsan";
String s3 = new String("zhangsan");
String s4 = "zhang" + "san"; 
String s5 = s + "san";
System.out.println("s1==s2:" + (s1 == s2)); // true
System.out.println("s3==s1:" + (s3 == s1)); // false
System.out.println("s5==s2:" + (s4 == s2)); // true
System.out.println("s6==s2:" + (s5 == s2)); // false

Shouldn't equals be used for string comparison? Why is this the result?

The first one: the source code of the String keyword is final modified, the string zhangsan has only one snapshot in the memory, the addresses pointed to by s1 and s2 are the same, and == compares the memory addresses, so the memory address values ​​of s1 and s2 are the same, so it is true.
The second one: s3 uses the new keyword. Using new will create a new one and store it in another place, so the memory address and pointing are different.
The third one: Same as the first one, except that the value of s4 has been spliced. After the spliced ​​result, jvm finds that it already exists, so it can directly point to the existing one, and there is no need to allocate wasted space.
Fourth: If you know that this way of writing will recreate a new object (you have been asked in the interview), then it is similar to the second one.
For example, new String(“zhangsan”)==new String(“zhangsan”); new String(“zhangsan”)==“zhangsan” is also false, similar to int

Data Accuracy and Calculation

// 精度丢失问题 float、double 不可直接计算,尤其是电商证券行业
double g1 = 0.1, g2 = 0.2;
System.out.println(g1 + g2); // 0.30000000000000004
System.out.println(BigDecimal.valueOf(g1).add(BigDecimal.valueOf(g2)).doubleValue()); // 刚好0.3 推荐这个
// 直接写小数,不声明的时候,默认小数都用double来表示,所以如果要用float的话,则应该在小数后加上f
// float dd = 3.4;  // 3.4是double类型,float dd = 3.4f 或者 float dd = (float)3.4才正确;
// 3*0.1==0.3将会返回 false, 精度不一样导致,因为前者相乘后是17位小数( 0.30...4)
System.out.println(1/3); // 0 整型 0.333...取整后是0
System.out.println(1.0/3.0); // 0.3333333333333333 带了小数点表示是double型,所以小数点后17位
System.out.println(1f/3f); // 0.33333334 // f表示float型,小数点后8位

Decimal point numbers, all those that are not declared are of double type, the number assigned is exactly the same number, but if you do addition, subtraction, multiplication and division, it will be 17 decimal places!!

Guess you like

Origin blog.csdn.net/qq_29539827/article/details/128633396