基础数据类型的比较

数据类型的知识确实很基础,但若没全面的搞清楚,面试中可能就要被鄙视了或者工作中一不小心就是一个严重bug。所以花点时间整理了一下。

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 ;
关于默认缓存数据范围,上限127可以改配置对其改大,但下限-128不能改。超出对应范围则会去创建新的对象,不超出直接取缓存

== 和 equals的区别 : 前者是比较内存地址的值,后者比较对象本身属性也就是实际值。

下面看比较代码与结果。(粗标题是速记总纲,代码内注释是详细释意,代码是例子)

一、两边变量都是int类型的一律相等 以下结果全部是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);

二.、两边变量都是包装类型的(不做运算直接比较), 非缓存数组范围内的 不论赋值方式 一律都不相等,因为超出都是new新的对象两个新变量的内存地址值是不相等的,且缓存范围内,两边变量只要任意一个出现new关键字就都是不相等的。总结下来就是只有Integer g = 10;Integer h = 10 这种情况相等且值在[-128,127] 因为取的是缓存没有去新new一个

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关键字出现

三.、两边变量都是包装类型的(做了运算在比较)一律相等,不论做运算的两个变量类型是否一致。以下结果全部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);

四.、两边变量数据类型不一致比较,一律相等 (自动拆箱装箱的原因)

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 关键词的源码里面是有final修饰的, 字符串zhangsan在内存里面只有唯一一个快照,s1和s2指向的地址都是同一个,而== 比较的是内存地址,所以s1s2的内存地址值相同所以true。
第二个: s3用了new关键词,用new就会新创建一个并在存在另外一个地方,所以内存地址就不相同了,指向也不一样。
第三个: 和第一个一样,只是s4的值进行了拼接而已,拼接后的结果jvm发现已存在了,就直接给指向这个已存在的就行了,就没必要再去分配浪费空间了。
第四个:如果你知道这种写法是会重新new一个对象的(面试中曾被问到过吧),那就和第二种类似了。
在比如new String(“zhangsan”)= =new String(“zhangsan”); new String(“zhangsan”)= =“zhangsan” 也都是false, 和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位小数点了!!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值