Java基础面试题第三篇

本文详细讲解了Java中Object的hashCode方法用途、hashCode与equals的关系,以及String、StringBuffer和StringBuilder的区别,强调了字符串不可变性和哈希碰撞的概念。
摘要由CSDN通过智能技术生成

目录

Java常见类

Object

hashCode()有什么用?

为什么要有hashCode?

那为什么不止提供hashCode()方法?

为什么两个对象有相同的hashCode值,它们也不一定是相等的?

为什么重写equals时必须重写hashCode()方法?     

String

String,StringBuffer,StringBuilder的区别?

String为什么是不可变的?

String#equals和Object#equals的区别?

字符串常量池的作用了解吗?

String s1 = new String("abc");这句话创建了几个字符串对象?


Java常见类

Object

hashCode()有什么用?

hashCode() 方法用于获取对象的哈希码(Hash Code),也成为散列码,它的主要作用是用于在哈希表等数据结构中进行快速查找、插入和删除操作。

为什么要有hashCode?

hashCode()和equals()都是用于比较两个对象是否相等 。

在使用哈希集合(如 HashSetHashMapHashtable 等)存储对象时,通过哈希码来确定对象的存储位置。这样可以在查找对象时快速定位到对象所在的位置,提高了查找效率。

那为什么不止提供hashCode()方法?

这是因为两个对象的hashCode值相等并不代表两个对象就相等。

为什么两个对象有相同的hashCode值,它们也不一定是相等的?

因为hashCode()所使用的哈希算法也许刚好会让多个对象返回相同的hash值。越糟糕的哈希算法越容易碰撞。

总结:

         如果两个对象的hashCode值相等,这两个对象不一定相等(哈希碰撞)

        如果两个对象的hashCode值相等并且equals方法也返回true,我们才认为这两个对象相等

        如果两个对象hashCode值不相等,我们直接认为这两个对象不相等。

为什么重写equals时必须重写hashCode()方法?     

        因为两个相等的对象的hashCode值必须想相等。   通过equals判断两个对象是否相等之前会先通过两个对象的hashCode值进行判断。如果两个对象的hashCode值不相等,直接认为两个对象不相等。        

String

String,StringBuffer,StringBuilder的区别?

  1. String(字符串常量):

    • String 类是不可变的,即一旦创建了字符串对象,就无法修改它的内容。每次对字符串进行修改(如拼接、替换等),都会创建一个新的字符串对象。
    • 字符串常量池中的字符串对象是唯一的,如果创建了一个内容相同的字符串常量,它们会共享同一个对象。
    • 因为字符串不可变性的特点,适用于字符串不经常变化的情况,例如表示常量、配置信息、数据库连接等。
  2. StringBuffer(线程安全的可变字符串):

    • StringBuffer 类是可变的,可以通过方法对字符串进行修改,而不会创建新的对象。
    • StringBuffer 是线程安全的,它的方法都是同步的,适用于多线程环境下的字符串操作。
    • 由于线程安全的特点,StringBuffer 的性能比较低,不适合在单线程环境下大量字符串操作。
  3. StringBuilder(非线程安全的可变字符串):

    • StringBuilder 类与 StringBuffer 类功能相似,也是可变的字符串对象,可以通过方法对字符串进行修改,而不会创建新的对象。
    • StringBuilder 不是线程安全的,因此它的性能比 StringBuffer 更高。
    • 由于不需要考虑线程安全问题,StringBuilder 适用于单线程环境下的大量字符串操作。

因此,根据需要选择合适的字符串类:

  • 如果字符串内容不经常变化,或者在多线程环境下,应该使用 String 类。
  • 如果在单线程环境下进行大量字符串操作,应该使用 StringBuilder 类。
  • 如果在多线程环境下进行字符串操作,应该使用 StringBuffer 类。

String为什么是不可变的?

  1. 保存字符串的数组被final修饰且为私有,并且String类没有提供/暴露修改这个字符串的方法
  2. String类被final修饰导致其不能被继承,进而避免了子类破坏String不可变。
  3. 在Java9之后,String,StringBuilder,StringBuffer的实现改用byte数组存储字符串。

String#equals和Object#equals的区别?

String中的euqals方法是被重写过的,比较的是String字符串的值是否相等。Object的equals方法比较的是对象的内存地址

字符串常量池的作用了解吗?

字符串常量池是JVM为了提升性能和减少内存消耗针对字符串专门开辟的一块区域,主要目的是为了避免字符串的重复创建。

String s1 = new String("abc");这句话创建了几个字符串对象?

会创建1或2个字符串对象。

  1. 一种情况是创建一个字符串对象: 如果字符串常量池中已经存在内容为 "abc" 的字符串对象,则这个代码只会创建一个字符串对象,因为 new String("abc") 不会在常量池中创建新的字符串对象,而是在堆中创建一个新的对象。

  2. 另一种情况是创建两个字符串对象: 如果字符串常量池中不存在内容为 "abc" 的字符串对象,则这个代码会创建两个字符串对象:一个是在常量池中创建的 "abc" 字面值字符串对象,另一个是在堆中创建的 new String("abc") 对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值