1.java:判断两个输入变量是源码否相等,如不相等则比较它们的源码大小。return可以放在三目运算式里吗?
2.public static <T> int binarySearch(List<?源码 extends T> list, T key, Comparator<? super T> c)
3.优雅的避坑不要轻易使用==比较两个Integer的值
4.《Lua5.4 源码剖析——基本数据类型 之 数字类型》
5.Java面试指南(一): int和Integer的区别
java:判断两个输入变量是否相等,如不相等则比较它们的源码大小。return可以放在三目运算式里吗?
可以的源码‘具体可以如下操作:判断两个变量是否相等的方式有两种:利用运算符 ==
利用equals方法
(1)比较基本Java基本数据类型
比较基本数据类型,只能用“==”,源码数源码燕窝价格不能用equals,源码这里比较的源码是两个变量的值;
(2)比较包装类
比较包装类,举个例子
1
2
3
4
5
6
7
8
9Integer i1 = new Integer();
Integer i2 = new Integer();
System.out.println(i1 == i2);
System.out.println(i1.equals(i2));
执行结果:
false
true
如上例子可知,源码“==”比较的源码是两个变量的内存地址值,equals比较的源码是两个具体要看当前这个类的equals方法
查看Integer的equals的源码1
2
3
4
5
6public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
return false;
可知比较的是两个变量的intValue;
或者int a,b
int max = a>b?a:b;
System.out.println(max);
==是运算符,用于比较两个变量是否相等,对于基本类型而言比较的是变量的值,对于对象类型而言比较的是对象的地址.
equals()是Object类的方法,用于比较两个对象内容是否相等.默认Object类的equals()实现如下:
不难看出此时equals()是比较两个对象的地址,此时直接==比较的的结果一样.对于可能用于集合存储中的对象元素而言,通常需要重写其equals()方法.
public static <T> int binarySearch(List<? extends T> list, T key, Comparator<? super T> c)
é®é¢1ï¼2å ¶å®å¯ä»¥ä¸èµ·è®²ï¼å°±æ¯ï¼ä½ 没å®å ¨ç解==ï¼equalsåèªå¨è£ ç®±ï¼auto boxing)ãä»ç»çä½ çcomparatorçå®ç°return i<j?-1:(i==j?0:1);è¿å¥è¯ï¼æ³¨æï¼ä½ çåæ°æ¯Integerç±»åï¼ä¸æ¯åºæ¬ç±»åintï¼ä½ 对类ç对象å==æä½ï¼æ¯æ¯è¾å®ä»¬æ¯å¦æ¯åä¸ä¸ªå¼ç¨ï¼èä¸æ¯ä»ä»¬çå¼æ¯å¦ç¸çãæ以ï¼ä½ ç¨è¿ä¸ªæ¯è¾å¨åäºåæç´¢ï¼ç»æè¯å®æ¯ä¸å¯é¢ç¥çãå½<å¤æ失败çæ¶åï¼åé¢ç==åºæ¬ä¸å¯è½æ¯trueï¼è¿ä¹æ¯ä¸ºä»ä¹if(integers.get(1)==new Integer(1)){ System.out.println("<3>");}è¿å¥è¯ä¸è½æå°åº<3>æ¥ãä½ åé¢é£ä¸ªå®ç°æ¯æ£ç¡®çï¼å 为类ç对象没æ<æä½å>æä½ï¼æ以ç¼è¯å¨ä¼æInteger对象èªå¨è½¬æintåæ§è¡æ¯è¾ã
é®é¢3ï¼apiåçå¾æ¸ æ¥ï¼å½æ¾ä¸å°çæ¶åï¼ä¼è¿åã-ï¼æå ¥å¼ï¼-1ãï¼å¨è¿ä¸ªç¨åºéï¼å ä¸ºä½ çæ¯è¾å¨åçä¸å¯¹ï¼æ以æ索失败ï¼å¹¶ä¸å®è®¤ä¸ºæå ¥å¼æ¯1ï¼è¿æ²¡æé®é¢åãå ¶å®ï¼å 为ä¸é¢è¯´çé®é¢ï¼ä»è¿åä»»ä½å¥å¥æªæªçæ°é½æå¯è½ã
å¦æä½ æ³å¯¹ä¸¤ä¸ªIntegerç±»ç对象æ¯è¾å¼ï¼ä½ å¯ä»¥è°ç¨i.eqauls(j);æè i.intValue()==j.intValue();intValueæ¹æ³è¿åçæ¯Integer对象å è£ çåºæ¬ç±»åçintå¼
å¦å¤ï¼è¡¥å ä¸ç¹ï¼ä¸ç¥éæ¯ä½ æè¿°çä¸å¥½ï¼è¿æ¯æç解çä¸å¯¹ãä½ è¯´çâæ ¹æ®APIæ档解éï¼ Comparatoråªæ¯å¨searchä¹å对listè¿è¡æåºãâä¸å¯¹ï¼binarysearchä¸ä¼æåºï¼èæ¯apiè¦æ±ä½ å¨è°ç¨binarySearchä¹åï¼å¿ é¡»ä¿è¯ä¼ è¿å»çlistæ¯å·²æåºäºçï¼ä½ å¯ä»¥è°ç¨Collections.sortæ¥å®ç°ï¼ä¹å¯ä»¥èªå·±åæåºç®æ³
=========================================================
comparatorçä½ç¨å°±æ¯æ¯è¾å¨åï¼åè¯æåºæ¹æ³ææ ·æ¯è¾ä¸¤ä¸ªå¼è°å¤§è°å°æç¸çï¼å¯¹äºIntegerï¼å½ç¶æ¯è¾è§åå¾ç´è§ï¼ä½æ¯å¯¹å«çç±»å¢ï¼æ¯å¦ä½ æä¸ä¸ªä¸ä¸ªStudentç±»ï¼ä½ å¸ææ ¹æ®å¦å·æ¥æåºï¼æ¥æ¾ï¼ä½ å°±éè¦å®ä¹èªå·±çComparatorï¼å½ç¶ä½ ä¹å¯ä»¥è®©ä½ çç±»å®ç°Comparableæ¥å£ï¼è¿æ ·ä½ å°±å¯ä»¥ç´æ¥è°ç¨binarySearchçå¦å¤ä¸ä¸ªä¸éè¦æ¯è¾å¨ççæ¬
=========================================================
æç¹ä¸æç½ï¼ä½ æ°è¡¥å çé®é¢æ¯é对æåªå¥è¯è®²çï¼ä½ è´´çAPIæ¯æ²¡éå¦ï¼ä½ç解ä¸å¯¹ãbinarySearchä¸ä¼æåºï¼æåºçæ¯sortï¼binarySearchå®ç°ä¸ä¸ä¼è°ç¨sortï¼è¿ç¹ä½ èªå·±çæºä»£ç å°±ç¥éäºï¼äºå®ä¸api表达çä¹æ¯è¿ä¸ªææï¼æ³¨æï¼åè¯æ¯âå¨è¿è¡æ¤è°ç¨ä¹åâï¼æææ¯ç¨æ·èªå·±è°ç¨sortåè°ç¨binarysearchï¼ãä½ ç¥épre-condition说æ³åï¼å表已æåºç¶æå°±æ¯binarySearchæ¹æ³æåçpre-conditionï¼åç½®æ¡ä»¶ï¼ï¼ä½ å¯ä»¥ä¼ ä¸ä¸ªä¹±åºçlistè¿å»ï¼æ²¡é®é¢ï¼ç¼è¯å¨ä¸ä¼æ¥éï¼ä½æ¯ä½ å¾ä¸å°èªå·±æ³è¦çç»æï¼è¿ä¸ªä½ èªå·±è¯å°±ç¥éäºã
=========================================================
æ±ããä½ çææé¾éä¸è¿æ¯searchä¼è°ç¨sortä¹ï¼å¦åï¼å¦æä½ æ¿è®¤searchä¸è°ç¨sortï¼é£ä¸ºä»ä¹è¿æçcomparatorä¼å¦åä¸æç´¢è¿ç¨ï¼å¦æsearchæ¢ä¸æåºï¼åä¸ä½¿ç¨comparatorï¼é£è¿ä¸ªåæ°ä¸å°±æ²¡æç¨äºåï¼
æ以ï¼searchéè¦comparatorï¼åªç¨æ¥æç´¢ï¼åæåºæ¯«æ å ³ç³»ãï¼ä½ åºè¯¥ç¥éäºåæç´¢æ¯æä¹æ§è¡çå§ï¼é£å°±å¾æ¸ æ¥ä¸ºä»ä¹éè¦ä¸ä¸ªcomparatoräºï¼
优雅的避坑不要轻易使用==比较两个Integer的值
直接进入主题,来看一段代码,源码让我们探索Integer比较的源码奥秘:
许多人可能会理所当然地认为这段代码会打印出 j = ,但背后的源码原理却值得深入探讨。i作为Integer对象,源码而j为基本类型int,它们如何协同工作呢?这涉及到Java 5引入的自动装箱和拆箱机制。借助IDEA的jclasslib Bytecode viewer插件,我们可以看到程序运行的底层指令:
这段程序的字节码指令揭示了自动装箱和拆箱的过程。第3行调用Integer的valueOf方法进行自动装箱,第8行则调用intValue方法进行自动拆箱,将Integer对象转换为int。
进一步研究valueOf和intValue的石岛有个叫什么源码头源码,我们发现Integer类中有一个IntegerCache机制,它在虚拟机初始化时预加载了(-,]范围内的整数。这解释了为什么i1 == i2为true,而i3 == i4为false:在缓存范围内,而超出了。
为了避免这类陷阱,正确的比较两个Integer值的方法是使用equals()函数,而不是简单的==。equals会比较两个对象的整数值,不受类型影响。
阿里Java开发手册推荐的策略是,当比较整型包装类对象的值时,始终使用equals()方法,以确保准确无误的比较。
《Lua5.4 源码剖析——基本数据类型 之 数字类型》
数字类型在编程中分为整数和浮点数两种。在Lua语言的5.3版本之前,所有数字都被底层实现为浮点数,整数的概念并未独立出来,而是通过浮点数的IEEE表示法进行表示与数据存储。这样,在进行整数运算时,可能会在多次运算后累积产生出意外的真龙出水主图指标公式源码浮点误差。因此,从Lua5.3版本开始,Lua引入了对整数的支持,使其不再依赖于浮点数进行表示,并且支持位运算等整数运算操作符。
在Lua语言中,每个基础对象需要存储其类型标识,这个标识在源码《lua.h》中定义为tt,数字类型的tt枚举值为LUA_TNUMBER(对应数字3)。由于数字类型分为整型和浮点型,它们通过类型变体来区分。在源码《lobject.h》中,类型变体LUA_VNUMINT表示整型,而LUA_VNUMFLT表示浮点型。
数字类型在TValue中定义了Value字段,这个字段包含i和n两个字段,用于分别存储整型和浮点型的数值。在历史原因的影响下,lua_Number并不是指所有数字类型,而是专门指浮点类型;lua_Integer则专门指整型。因此,设置整数或浮点数时,易语言一键下载解压源码需要先设置Value字段中的n字段(整型)或i字段(浮点型),然后使用settt_宏设置type tag(tt)字段为对应值LUA_VNUMFLT或LUA_VNUMINT。
在底层,数字类型的数据类型具体表现为lua_Integer和lua_Number。在源码《lua.h》中声明,lua_Number为LUA_NUMBER,lua_Integer为LUA_INTEGER。深入学习它们的定义,可以看到整型有int、long、long long三种类型,浮点型有float、double、long double三种类型。Lua5.4的默认配置中,整型使用long long类型,浮点型使用double类型。在Windows平台上,整型使用__int类型。
至此,数字类型的讲解就告一段落。希望本文对理解Lua语言中的城通网盘在线直链解析源码数字类型有所帮助。
Java面试指南(一): int和Integer的区别
即将迎来跳槽的高峰期,也就是常说的“金三银四”。由于本人年前就已经开始了求职面试的征程,直到现在才算尘埃落定,所以应该不会再加入跳槽大军了。“Java面试指南”这个系列的文章,主要是记录我在面试中整理的知识点和扩展思考,希望能对你有所帮助。
面试中的回答没有标准答案,只要能清楚表达关键点即可,所以文中的答案仅供参考。
今天的问题是:int和Integer的区别是什么?在继续阅读之前,我希望你能停下来思考一下:如果面试时面试官问你这个问题,你会怎么回答?
一、面试回答
int是Java中的整型数字,是Java的8种原始数据类型之一,其他七种是:boolean、byte、short、char、float、long、double。尽管Java中一切都是对象,但这八种数据类型是一个例外。
Integer是Java中int类型的包装类,有一个int类型的类变量value储存数据,并提供了基本的数学运算和类型转换。
Java5引入了自动装箱/拆箱,编译阶段会根据上下文自动进行转换。装箱会调用Valueof(),拆箱会调用intValue。从Java9开始,Integer的构造器被标记为废弃,官方文档要求使用Integer的静态工厂类ValueOf方法。
Integer类的ValueOf方法中有一个缓存机制,会先对数值进行判断,如果数值在默认的[-:]之间,则返回缓存的对象,否则返回一个新的Integer对象。上限可以通过JVM提供的配置(-XX:AutoBoxCacheMax)进行修改。
二、深入理解
一般来说,很少有面试官会在面试时问到int和Integer的区别,而有关缓存的考点更多会出现在笔试题中。但这并不代表我们不需要关注和理解。例如,在日常编码时,什么时候该用int,什么时候该用Integer,你是否真的清楚?
(一)、缓存机制
所谓的缓存机制,就是基本类型的包装类为了提升效率和节约内存而引入的机制。除了Integer类默认情况下缓存了[-:]之间的数值外,其他基本类型(除了Float和Double)都有缓存对象。
(二)、自动装箱/拆箱
谈及基本数据类型与包装类,自然会聊到自动装箱和拆箱。这两种行为是Java中提供的语法糖之一,即Java平台为了方便程序开发,而在底层进行的一些转换操作。这种语法对语言本身功能而言并不会产生什么影响,转换的工作发生在编译阶段。
以int和Integer为例,在日常编码时我们更习惯于直接将整数赋值给变量,而不是使用Integer.Valueof()方法,但代码的运行结果是一致的。
使用javac编译这两行代码后,再用javap查看编译后的class文件,就能看到:
(三)、基本类型的线程安全
由于JVM直接保证的原子性变量操作包括read、write、assign、store、load,大致可以认为基本数据类型的读写是具备原子性的(除了long和double,这两种基本类型的读写原子性依赖于虚拟机的具体实现,因为对于没有使用volatile修饰的位的数据结构,Java虚拟机规范是允许分两次来操作的)。
除了读写操作外,对基本类型的变量操作都是非线程安全的,需要利用相关的并发技术来保证线程安全,比如加锁或者使用JUC下的Atomic开头的线程安全类。
(四)、源码阅读
Integer类从整体上来看,主要包括了用于表示最大值、最小值、位数等信息的常量,将各种其他类型转换为Integer对象的静态工厂方法valueOf()以及将整数转换为其他基本类型的方法,如byteValue()、shortValue()等等,还提供了进制转换的方法,如toBinaryString()用于将整数转换为二进制字符串。
1. Integer源码
Integer是不可变类,使用了final修饰class,表明Integer无法被继承,使用final修饰的value属性来保存数字,即一旦Integer对象创建后,数值就不会再改变。
Integer的最大值为0x7fffffff,转换成十进制为2^-1,最小值为0x,转换成十进制是-2^。使用常量SIZE=来表示int的位数,即位。因为int是有符号数,需要一位来表示正负号,所以剩下的位用来表示实际的数值。
2. Integer的缓存机制
Integer缓存的对象保存在Integer的内部类IntegerCache中,static语句块中是缓存对象的生成逻辑。默认情况下,- ~ 范围内Integer对象保存在Integer数组中。
static语句块会在初始化阶段,由虚拟机执行方法时执行。虚拟机会保证同一时间只会有一个线程执行方法,所以是线程安全的。而cache数组对象是单例,也就是说IntegerCache采用了单例模式。
三、小结
尽管面试中直接问到int和Integer的区别的几率并不大,而且也没有特别多可以展开细说的知识点,但关于Integer的源码,建议还是要去阅读了解。最后,祝君面试顺利,薪资翻倍!
END