获得徽章 0
- @java李杨勇、@墨理学AI,新的一天,来一起学习在开发中最常遇到的问题吧!
问题:Integer类型比较,猜猜下面返回什么结果
public static void test3(){
Integer a = 127;
Integer b = 127;
Integer c = 128;
Integer d = 128;
System.out.println(a == b);
System.out.println(c == d);
System.out.println(c.equals(d));
}
解答:答案是true、false、true,你猜对了?
为什么会出现这样的结果呢,因为是Integer缓存了-128到127的数值,当使用"=="比较符时,实际上比较的是两个对象的地址,因为Integer将-128到127的数值都进行了缓存,所以在这个范围内的相同的两个值无论是使用==还是equals比较结果都是true,因为它们是直接取的缓存中的值,但是不在这个范围内的话,则返回的是false。
缓存源码:【图1】
当使用的是equals方法比较时,不在这个范围内的相同的两个值返回的结果也是true,因为Integer内部重写了equals方法,该方法比较的是两个对象的中的值而不是地址。
建议:使用包装类比较值时,不要使用"==",而应该使用equals方法。展开评论3 - @java李杨勇、@墨理学AI,新的一天,来一起学习在开发中最常遇到的问题吧!
1、抽象类和接口的区别
一: 相同点
都不能直接实例对象,都可以包含抽象方法
二: 不同点
1、接口中除了静态方法和默认方法外只能存在抽象方法,但是抽象类中既可以存在抽象方法也可以存在非抽象方法。
2、接口可以多实现,但是类只能单继承
3、接口中只能定义常量,抽象类中可以定义常量和变量
4、接口中没有构造函数,抽象类中有构造函数
2、重写equals方法需要注意的事项
注: java规范中要求重写equals方法需要具有以下的特性:
1、自反性: 针对非空的x,使用x.equals(x)应该返回true
2、对称性: 针对x,y,如果x.equals(y)为true,那么y.equals(x)也应该为true
3、传递性: 如有x,y,z,存在x.equals(y)和y.equals(z)都为True,那么x.equals(z)也应该为true
4、一致性: 如果比较对象未发生改变,则反复调用equals方法应该返回同样的结果
5、对于任意的非空x,x.equals(null)应该返回false展开评论4 - @java李杨勇、@墨理学AI,新的一天,来一起学习在开发中最常遇到的问题吧!
二、使用增强for循环删除元素,猜猜下面代码会输出什么?
List<String> list = new ArrayList<>();
list.add("淘宝");
list.add("淘宝");
list.add("掘金");
for(String item : list) {
if("淘宝".equals(item)) {
list.remove(item);
}
}
解答:直接抛出ConcurrentModificationException异常,其实增强for循环只是一个语法糖,方便开发者使用,在虚拟机实际的被执行的时候是通过迭代器的方式循环,对上面的代码进行反编译得到如下代码:【图1】
为什么使用迭代器循环方式在循环的时候删除元素会抛出这个异常呢?实际上,迭代器在每次调用next()方法的时候,第一步就会先去执行checkForComodification()方法,这个方法的目的就是检查list下的modCount是否和expectedModCount变量的值一致(可以理解为版本号),如果不一致,则直接抛出ConcurrentModificationException异常。
删除的流程是这样的呢?实际上modCount变量表示的含义是集合被修改的次数,每次对集合进行add或者remove的时候,则会对它进行+1,在调用集合的remove方法时,该变量的值会被加1,但是expectedModCount的值却没有变动,此时,当再次执行next方法时判断则两者值不相等,于是抛出异常。【图2】
解决方案:使用迭代器的remove方法,即将上面删除的代码修改为: iterator.remove(),在迭代器的remove方法中,会将modCount的值赋值给expectedModCount,所以在下次执行next方法的时候,两者的值还是一样的,就不会抛出异常。
因为沸点字数有限制,更多原因请看:【图3】分析展开14 - @java李杨勇、@墨理学AI,新的一天,来一起学习在开发中最常遇到的问题吧!
一、常见的集合删除元素问题:使用for循环匹配某个元素,然后删除,猜猜下面代码输出的会是什么?
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("淘宝");
list.add("淘宝");
list.add("掘金");
for (int i = 0; i < list.size(); i++) {
if ("淘宝".equals(list.get(i))) {
list.remove(i);
}
}
System.out.println(list);
}
解答:输出【淘宝、掘金】,本意我们是想删除集合中为“淘宝”的元素,但是因为在循环中使用到list的remove方法,这样一旦有元素被移除后,集合的size会变小,这样原本的元素左边就会改变,最终循环提前退出,具体可看下面图纸解析:
解决方案:
方式1:在调用remove方法后添加:i--,让下一轮坐标重新回到删除元素的前一个(因为这样删除会让被删除元素之后的元素左边都往前移一位)
方式2:使用java8提供的removeIf API,完整代码:list.removeIf(e -> “淘宝”.equals(e)) 即可实现。展开78
![[奸笑]](http://lf-web-assets.juejin.cn/obj/juejin-web/xitu_juejin_web/img/jj_emoji_17.bcebf79.png)