装箱和拆箱
对于java基础类型,比如Integer,Short,Long
Integer i =1; 基本类型转成对象就是装箱
int i2 = new Integer(1); 对象自动变成基础类型就是拆箱
理解起来就是不用Integer i = (int) 1;所以叫自动的
一般出题目都会考内部缓存的机制。
java对于Integer.valueOf("1")这种内部是会缓存的
参考代码:
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
对于valueOf这种调用才会触发-128到127的缓存复用
但是直接new对象是不会触发到缓存的
Integer i = new Integer(1);
Integer i2 = new Integer(1);
例题训练
Integer i1 = Integer.parseInt("1");
Integer i2 = Integer.parseInt("1");
Integer i3 = new Integer("1");
Integer i4 = 1;
System.out.println(i1==i2);
System.out.println(i3==i2);
System.out.println(i3==i4);
System.out.println(i1==i4);
参考源码分析对于parseInt或者valueOf都是自带-128到127的缓存的
所以打印true false false true
分析Short
对于short类型,也是支持装箱的;
Short和Integer,Long,Object
首先看一道题目
Short s1 =1;
Integer s2 =1;
Long s3 = 1;
Object s4 = 1;
可以一个个打印地址,发现s1和s2是不equal的,也自然不相等;
但是和s4是相等的。
可以看一下Short的valueOf,发现类型不一样直接返回false,所以short类型的1和
integer类型的1是不一样的
public boolean equals(Object obj) {
if (obj instanceof Short) {
return value == ((Short)obj).shortValue();
}
return false;
}
再看一道题:
HashSet<Short> hashSet = new HashSet<>();
for (int i = 0;i< 100;i++) {
hashSet.add((short) i);
hashSet.remove(i - 1);
}
System.out.println(hashSet.size());
这道题目也是各种骚操作,主要是添加的是Short类型,删除的时候装箱自动转成Integer,而HashSet默认是HashMap实现的,判断key是否一致是判断hashCode,默认也就是内存地址,前面说了short类型的1和Integer类型的1既不内存地址一样也不equals
改一下,改成如下,就顺利删除了;
HashSet<Integer>hashSet = new HashSet<>();
for (int i = 0 ; i< 100; i++) {
hashSet.add( i);
hashSet.remove(i - 1);
}
System.out.println(hashSet.size());
另外这道题的删除,HashSet不能和数组remove混为一谈,因为删除是1这个对象,而不是数组中index=1的对象;但是对于数组,remove()参数既可以是int也可以是对象
ArrayList<Integer>list=new ArrayList<>();
list.add(1);
list.remove(1);
System.out.println(list.size());