基础很重要,基础很重要,基础很重要。重要的事情说三遍,。

今天聊一聊Java的数据比较,这个范围比较大,基础类型的比较、引用类型的比较。

前提:

1、Java和c#都提供自动装箱和自动拆箱操作,何为自动装箱,简单点说就是将值类型转换成为引用类型,自动拆箱就是将引用类型转换成为值类型。并且我们还经常被教导,要避免自动的装箱和拆箱操作,因为这个会影响性能。

2、比较常用的运算符是==,equals。

下面分几类来说明数据的比较,

引用类型之间的比较:Integer与Integer之间的比较、Boolean与Boolean之间的比较、Integer与Boolean之间的比较

值类型之间的比较:int与int之间的比较、int与bool之间的比较

值类型与引用类型之间的比较:Integer与int之间的比较、Boolean与bool之间的比较

开工

引用类型之间的比较--Integer与Integer之间的比较

简单说明一下,Integer是引用类型,代表的是整形数字

上代码

1 public static void main(String[] args) throwsException {2 Integer integer = new Integer(0);3 Integer mInteger = Integer.valueOf(0);4 Integer sInteger = 0;5

6 System.out.println(integer == mInteger);//false

7 System.out.println(integer == sInteger);//false

8 System.out.println(mInteger == sInteger);//true

9

10 System.out.println(memoryAddress(integer));11 System.out.println(memoryAddress(mInteger));12 System.out.println(memoryAddress(sInteger));13

14 }15

16 private static intmemoryAddress(Object object) {17 //内存地址会有所不同

18 returnSystem.identityHashCode(object);19 }

执行结果:

分析:

1、执行结果和我们预想的不太一样,引用类型是在堆上存放的,每个引用的地址应该都不相同。但是mInteger == sInteger  执行结果为true,并且mInteger ,sInteger的内存地址是相同的。

2、要分析这个原因,我们需要了解Java设计者为了性能而进行的一些努力,查看Java源代码,可以看到Integer的valueof方法里面包含了一个缓存:其中IntegerCache.low =-127,IntegerCache.high=128

1 @HotSpotIntrinsicCandidate2 public static Integer valueOf(inti) {3 if (i >= IntegerCache.low && i <=IntegerCache.high)4 return IntegerCache.cache[i + (-IntegerCache.low)];5 return newInteger(i);6 }

对于使用Integer.valueof()方法,如果数值是-127至128,那么会使用缓存对象,否则会new一个对象。

3、Integer sInteger = 0;   发生了什么呢?自动装箱,等价于Integer sInteger=Integer.valueOf(0)。通过这个,我们就可以得出比较等于true的原因了,都是从缓存中读取的对象,难怪内存地址会一致。

引用类型比较--Integer与Integer引用类型比较   使用equals

上代码:

1 public static void main(String[] args) throwsException {2 Integer integer = new Integer(0);3 Integer mInteger = Integer.valueOf(0);4 Integer sInteger = 0;5

6 System.out.println(integer == mInteger);//false

7 System.out.println(integer == sInteger);//false

8 System.out.println(mInteger == sInteger);//true

9

10 System.out.println(memoryAddress(integer));11 System.out.println(memoryAddress(mInteger));12 System.out.println(memoryAddress(sInteger));13

14 System.out.println(integer.equals(mInteger));//true

15 System.out.println(integer.equals(sInteger));//true

16 System.out.println(mInteger.equals(sInteger));//true

17

18 }19

20 private static intmemoryAddress(Object object) {21 //内存地址会有所不同

22 returnSystem.identityHashCode(object);23 }

分析:使用equals比较,只要数值相同,那么比较结果就是相同。查看Java源代码:

1 public booleanequals(Object obj) {2 if (obj instanceofInteger) {3 return value ==((Integer)obj).intValue();4 }5 return false;6 }

可以看到Integer的equals比较,其实比较的就是数值。

值类型之间的比较:int与int

上代码

1 int m=0;2 int i=0;3 int s=0;4 System.out.println(m==i);//true5 //值类型是没有equals方法6 //System.out.println(m.equals(i));

分析:对于int 的比较,无需多言,本来就是数值比较。

Integer与int的比较:

1 Integer integer = new Integer(0);2 Integer mInteger = Integer.valueOf(0);3 Integer sInteger = 0;//等价于Integer。valueof

4 int i = 0;5 System.out.println(integer == i);//true

6 System.out.println(mInteger == i);//true

7 System.out.println(sInteger == i);//true

8 System.out.println(integer.equals(i));//true

9 System.out.println(mInteger.equals(i));//true

10 System.out.println(sInteger.equals(i));//true

分析:

1、Integer类型与int类型通过==比较,Integer会自动拆箱,转换成int数值进行比较

2、equals方法更是读取对应的int数值进行比较。

因此引用类型与值类型之间的比较,使用equals与==都可以。

简单总结:

1、引用类型之间的比较,由于存在-127至128之间的缓存对象,因此使用== 进行比较存在风险。优先使用equals进行比较

2、引用类型与值类型进行比较,由于会自动拆箱,因此使用==和equals都可以正确得到结果

3、建议在实际编码过程中,对数值的比较使用equals

深入总结:

不仅仅Integer,其他的基本类型也都存在缓存,下面给出一个简单图表进行说明

基本类型

装箱类型

取值范围

是否缓存

缓存范围

byte

Byte

-128~127

-128~127

short

Short

-2^15 ~ (2^15 - 1)

-128~127

int

Integer

-2^31 ~ (2^31 - 1)

-128~127

long

Long

-2^63 ~ (2^63 - 1)

-128~127

float

Float

--

double

Double

--

boolean

Boolean

true、false

true、false

char

Character

\u0000 ~ \uffff

\u0000 ~ \uffff

Java博大精深,要想深入,基础必须要好,才能避免bug。

我们程序员的职责就是少写bug,这才是我们一直学习的动力。

java int short区别_Java基础之数据比较Integer、Short、int、short相关推荐

  1. java io流 教程_Java基础教程:IO流与文件基础

    Java:IO流与文件基础 说明: 本章内容将会持续更新,大家可以关注一下并给我提供建议,谢谢啦. 走进流 什么是流 流:指的是从源到目的地的字节的有序序列. 在Java中,可以从其中读取一个字节序列 ...

  2. java white case语句_JAVA基础(一)

    JAVA 关键字 关键字含义 abstract表明类或者成员方法具有抽象属性 assert用来进行程序调试 boolean基本数据类型之一,布尔类型 break提前跳出一个块 byte基本数据类型之一 ...

  3. java 锁旗标_Java基础知识点整理(一)

    1.&和&&的区别? &:逻辑与(and),运算符两边的表达式均为true时,整个结果才为true. &&:短路与,如果第一个表达式为false时,第二 ...

  4. java继承和多态_Java基础继承与多态

    Java基础第九天 继承概述 引入 首先我来写两个代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15//定义学生类 class Student { public void  ...

  5. 5 java中的集合类_java基础(5)-集合类1

    集合的由来 数组是很常用的一种数据结构,但假如我们遇到以下这样的的问题: 容器长度不确定 能自动排序 存储以键值对方式的数据 如果遇到这样的情况,数组就比较难满足了,所以也就有了一种与数组类似的数据结 ...

  6. java方法的传递方式_JAVA基础--方法传参

    JAVA基础--方法传参 为啥拿这个当话题? 在初学者阶段,许多童鞋都对方法传参比较迷茫,知其然不知其所以然. 一.先说说参数传递的几个术语: 值调用(call by vale):表示方法接收的是调用 ...

  7. java怎么快速补缺_Java基础查漏补缺(1)

    Java基础查漏补缺 String str2 = "hello"; String str3 = "hello"; System.out.println(str3 ...

  8. 三 java的基本数据类型_JAVA基础(三)--JAVA基本数据类型

    前两篇已经将开发环境搭建完成,如果你已经按之前的教程按部就班的完成了部署,那么世界上最优秀的编程语言之一和世界上最优秀的IDE之一已经出现在你的电脑上(此处应有掌声),如果你还没入门,或者正在台阶上踱 ...

  9. java键盘输入运算符_Java基础学习-三元运算符和键盘录入的基本步骤和使用

    1.键盘录入数据概述 我们目前在写程序的时候,数据值都是固定的,但是实际开发中,数据值肯定是变化的,所以,把数据改进为键盘录入,提高程序的灵活性. 2.如何实现键盘录入数据呢?(目前先记住就行) 导包 ...

  10. java上课笔记大全_JAVA基础知识上课笔记

    1.八种数值类型: int short long float double char byte boolean 2.两次转换类型:自动类型转换,强制类型转换. 在某种条件下系统自动完成类型转换, 1) ...

最新文章

  1. 万能 Transformer,你应该知道的一切
  2. Oracle笔记----oracle数字类型number自增
  3. 校运动会c语言程序编写,校运动会管理系统报告C语言(含完整代码)
  4. 爬虫-视频资源的爬取
  5. C语言的构造函数与析构函数
  6. yii mysql条件查询_mysql – 在Yii2 find()/ QueryBuilder中使用WHERE条件的SELECT子查询
  7. 并发之AtomicIntegerFieldUpdater
  8. java数组base64编码,java将base64编码字符串还原为字节数组
  9. 【最新砍价小程序源码】
  10. CodeBlocks下载与安装教程
  11. 非线性控制1.0——模糊控制理论基础
  12. 爬虫 | 破解APP中阿里云滑动验证码
  13. 【qq机器人】发送表情包
  14. qt mysql图形界面_qt数据库界面
  15. mybatis采坑之 PageHelper.startPage出现两个limit情况
  16. PostgreSql扩展(EXTENSION )
  17. Trajectory Planning (1)——五次、七次多项式
  18. 使用HTML实现一个静态页面(含源码)
  19. java.sql.SQLException: Undefined Error
  20. 鸿蒙与苹果性能,任正非谈鸿蒙:两三年,鸿蒙系统可与苹果系统相媲美,能否现实?...

热门文章

  1. SLE12 Server 在线安装MySQL Server
  2. Kotlin初学者笔记
  3. 2018年1月西邻雪山自驾游攻略
  4. 论文到底怎么降重才有效
  5. java线程栅栏_Java 多线程之栅栏-CyclicBarrier
  6. 输入一个十六进制的字符串,输出其相应的十进制数。
  7. 基于51单片机的俄罗斯方块游戏
  8. 统计检测(statistical tests)
  9. 利用JavaScript批量删除QQ空间说说(只需一个浏览器)
  10. ubuntu 下,用户,文件夹,用户组 之理解