기본 데이터 유형 비교

데이터 유형에 대한 지식은 참으로 매우 기초적이지만 완전히 이해하지 못하면 면접에서 멸시를 당하거나 직장에서 조심하지 않으면 심각한 버그가 발생할 수 있습니다. 따라서 잠시 시간을 내어 정리하십시오.

8가지 기본 데이터 유형 및 해당 패키징 유형 :
byte, short, int, long, float, double, boolean, char
Byte, Short, Integer, Long, Float, Double, Boolean, Character
캐시 범위 정보

Byte, Short, Integer, Long 4개의 패키징 클래스는 기본적으로 [-128, 127]의 캐시 데이터를 생성하고, Character는 기본적으로 [
0,127]의 캐시 데이터를 생성하며,
Boolean은 true 또는 false를 직접 반환합니다
. 해당 범위를 초과하면 새 개체가 생성되며 캐시가 직접 초과되지 않습니다.

==와 equals의 차이점 : 전자는 메모리 주소의 값을 비교하는 것이고 후자는 객체 자체의 실제 값을 비교하는 것입니다.

비교 코드와 결과를 살펴보겠습니다. (대략적인 제목은 약식 개요, 코드 내 주석은 자세한 설명, 코드는 예시임)

1. 양쪽의 변수는 모두 int 타입으로 동일하므로 다음 결과는 모두 참이다 .

// 基本类型的比较都是相等(不论赋值方式、即使值做了运算),也不区分是否超出缓存范围
 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. 양쪽의 변수는 래핑 유형(계산 없는 직접 비교) 이며 비캐시 배열의 범위 내에서는 할당 방법에 관계없이 동일하지 않습니다. 새 개체의 범위를 벗어난 두 개의 새 변수의 메모리 주소 값이 동일하지 않기 때문이며 캐시의 범위 내에서 양쪽의 변수 중 하나가 new 키워드로 나타나는 한 모두 동일하지 않습니다. 요약하면 정수 g = 10, 정수 h = 10만 같고 값은 [-128,127]입니다 .

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. 계산에 사용된 두 변수 유형이 일치하는지 여부에 관계없이 양쪽의 변수는 패키징 유형(계산 후 비교)이 동일합니다 . 다음 결과는 모두 사실입니다.

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. 양쪽 변수의 데이터 타입이 일치하지 않고 비교되며 모두 동일함 (자동 언박싱 및 패킹 이유)

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);

최종 요약은 다음과 같습니다

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

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

래퍼 유형의 비교는 equals 또는 래퍼 클래스에서 제공하는 .intValue() 메서드에 의해 int 유형으로 변환되어야 합니다.

문자열 유형에 대해서는 다음 코드를 참조하십시오.

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

문자열 비교에 equals를 사용하면 안 됩니까?왜 이것이 결과입니까?

첫 번째: String 키워드의 소스 코드가 최종 수정되었으며, zhangsan 문자열은 메모리에 스냅샷이 하나만 있고, s1과 s2가 가리키는 주소가 동일하고 == 메모리 주소를 비교하므로 s1과 s2의 메모리 주소 값이 동일하므로 참입니다.
두 번째: s3은 new 키워드를 사용하는데, new를 사용하면 새로 만들어서 다른 곳에 저장하기 때문에 메모리 주소와 포인팅이 다릅니다.
세 번째: s4의 값이 스플라이싱된 것을 제외하고는 첫 번째와 동일합니다.
넷째: 이 글쓰기 방식이 새로운 대상을 재창조한다는 것을 알고 있다면(인터뷰에서 요청받았습니다), 그러면 두 번째와 유사합니다.
예를 들어 new String("zhangsan")==new String("zhangsan"); new String("zhangsan")=="zhangsan"도 거짓이며 int와 유사합니다.

데이터 정확성 및 계산

// 精度丢失问题 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位

소수점 숫자, 선언되지 않은 것들은 모두 double형이고, 할당된 숫자는 정확히 같은 숫자인데 덧셈, 뺄셈, 곱셈, 나눗셈을 하면 소수점 이하 17자리가 됩니다!!

추천

출처blog.csdn.net/qq_29539827/article/details/128633396