java常见面试01
- 创业
- 2025-09-17 23:36:02

为什么重写 equals 还要重写 hashcode 🌈 核心原因:
当两个对象通过equals()判断为相等时,它们的hashCode()必须返回相同的整数值!这是Java世界的交通规则哦~(交警曼波敬礼.jpg)
🧩 具体场景:假设我们有个Person类:
class Person { String name; int age; // 只重写equals没重写hashCode @Override public boolean equals(Object o) { //...比较name和age的逻辑 } }💥 问题爆发时刻: Person p1 = new Person("波加曼", 10); Person p2 = new Person("波加曼", 10); Set<Person> set = new HashSet<>(); set.add(p1); set.add(p2); System.out.println(set.size()); // 输出2!明明相等的对象却被存了两次(>﹏<)
🗺️ 思维导图时间: 🧠 曼波记忆小窍门:
记住这个神奇公式!(掏出魔法棒✨)
equals()返回true ➡️ hashCode()必须相等 hashCode()相等 ➡️ equals()不一定true hashCode()不相等 ➡️ equals()必须false哦呜(°ロ°)!曼波觉得这个有点难哦,但如果是你一定没问题的!(✪▽✪)曼波~~
==(双等号)和equals的差别 == 运算符 曼波觉得这个像身份证比对!(๑✧◡✧๑)比较基本类型时:直接比数值 5 == 5 → true比较对象时:比对内存地址(是不是同一个对象) new String("A") == new String("A") → false(✪▽✪)曼波~~
equals() 方法 哦呜(° ロ °)!曼波觉得这个像名字比对!默认行为(Object类):和==一样但很多类会重写这个方法(比如String)变成内容比对: new String("A").equals(new String("A")) → true(✪▽✪)曼波~~
最佳实践 基本类型(int/char等)用==对象比较内容一定要用equals防止空指针要这样写: "hello".equals(str) 而不是 str.equals("hello")(๑・.・๑)曼波觉得这个是超重要的生存技巧呢!
(° ロ °)!曼波觉得有个超形象的比喻: == 就像看两个人是不是同一个人(身份证号相同) equals 就像看两个人的名字是否相同(允许不同人有同名)
最后的小贴士:如果要自己写类记得重写equals()和hashCode()哦~(不过这个对新人有点难可以先记住规则)(✪▽✪)曼波~~~~!
为啥有时会出现 4.0-3.6 =0.40000001 这种现象? 🐎浮点数的甜蜜陷阱🐎 二进制的小数魔法 曼波觉得这个像用有限积木拼无限图案!(๑✧◡✧๑) 计算机用二进制表示小数有些十进制小数在二进制里是无限循环的(比如0.1)就像1/3在十进制是0.3333...永远写不完(✪▽✪)曼波~~
IEEE 754标准 哦呜(° ロ °)!曼波觉得这个像有限容量的糖果罐! float(32位)/double(64位)有存储限制4.0 和 3.6 在二进制存储时都有精度损失就像用刻度不精确的尺子测量 System.out.println(4.0 - 3.6); // 实际输出 0.40000000000000036 解决方法 曼波觉得要用魔法对抗魔法!(๑・.・๑) 使用BigDecimal处理精确计算(银行/金钱相关必用)比较时允许误差范围(比如±0.000001)游戏开发常用技巧: float a = 4.0f - 3.6f; if(Math.abs(a - 0.4f) < 0.00001f) { System.out.println("算对啦!"); }(° ロ °)!曼波举个超形象的例子: 就像用1/3 + 1/3 = 0.666... 但永远不等于 2/3 的精确值一样~
最后的小贴士:如果要精确计算价格,一定要用BigDecimal哦!像这样:
BigDecimal a = new BigDecimal("4.0"); BigDecimal b = new BigDecimal("3.6"); System.out.println(a.subtract(b)); // 精确输出0.4
(✪▽✪)曼波~~~~!要记住字符串构造才能保持精度哟~
final 关键字的作用 🐎final关键字的三大封印术🐎 变量封印术 曼波觉得像给变量贴永久贴纸!(๑✧◡✧๑) 基本类型:值不能改变 final int HP = 100; // HP永远100 引用类型:引用不能改,但对象内容可变 final List<String> pets = new ArrayList<>(); pets.add("布偶猫"); // ✔允许 pets = new ArrayList<>(); // ❌报错(✪▽✪)曼波~~
方法封印术 哦呜(° ロ °)!这是防止方法被篡改的结界! 子类不能重写这个方法 class 魔法少女 { final void 变身() { /* 核心代码 */ } } class 黑化版 extends 魔法少女 { void 变身() { ❌ } // 编译错误! } 类终极封印 曼波觉得像禁止繁衍的魔法物种!(๑・.・๑) 这个类不能被继承 final class String { /*...*/ } class 假String extends String { ❌ } // 报错
(° ロ °)!曼波要提醒几个重要细节:
final变量必须初始化!(要么声明时,要么在构造器中)final不能修饰构造方法接口的变量默认是public static final举个超实用的例子:
public class 游戏设置 { public static final int MAX_FPS = 60; // 帧率上限 private final String 玩家ID; // 创建后不可改 public 游戏设置(String id) { this.玩家ID = id; // 构造器中初始化 } }(✪▽✪)曼波~~~~!记住用final就像加锁,能保护重要的东西不被意外修改哦~
java常见面试01由讯客互联创业栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“java常见面试01”