前言:
本篇文章主要讲解Java中的几个类常被问到的面试题相关知识。该专栏比较适合刚入坑Java的小白以及准备秋招的大佬阅读。
如果文章有什么需要改进的地方欢迎大佬提出,对大佬有帮助希望可以支持下哦~
小威在此先感谢各位小伙伴儿了
以下正文开始
文章目录
- Java中的String类
- String类的特点
- String类创建对象方式
- String类常用方法
- Java中的StringBuffer类
- StringBuffer类的特点
- StringBuffer类的方法
- Java中的StringBuilder类
- StringBuilder类特点
- StringBuilder类方法
- String,StringBuffer,StringBuilder三者之间的区别
- Java中的包装类
- 书籍推荐
Java中的String类
首先我们介绍下Java中的String类,它是被final关键字修饰的类,因此不可被继承。String类在Java中是特别常用的类,它提供了许多便捷操作字符串的方法,如字符串拼接、分割、替换、截取、大小写转换等等。
String类的特点
Java中的String类具有以下特点:
- 不可变性:String类一旦被创建,其内容不可变,任何对String对象的修改都将返回一个新的String对象,原对象的内容不会改变。
- 线程安全:String类是线程安全的,可以被多个线程共享访问。
- 字符串常量池:String类在内存中维护了一个字符串常量池,使得相同内容的字符串只会在常量池中创建一次,减少了内存的消耗。
String类创建对象方式
在面试的时候面试官经常问到这个问题。下面我们详细介绍下:
Java中创建字符串对象有两种方式
直接使用双引号创建字符串对象。例如:
String str = "Hello, world!";
这种方式会先检查字符串常量池中是否存在该字符串,如果存在则直接返回该字符串的引用;如果不存在,则在常量池中创建一个新的字符串对象,并返回其引用。使用new关键字创建字符串对象。例如:
String str = new String("Hello, world!");
这种方式会在堆上创建一个新的字符串对象,并将指向该对象的引用返回。与第一种方式不同,使用new关键字创建的字符串对象不会进入字符串常量池中,而是直接存储在堆中。
而字符串常量池具有缓存的作用,因此当我们需要频繁创建字符串对象时,可以优先考虑使用直接双引号方式来创建,以提高效率和减少内存占用。
String类常用方法
下面是String类的常用方法:
length():返回此字符串的长度。
charAt(int index):返回指定索引处的字符。
substring(intbeginIndex, int endIndex):返回一个新字符串,它是此字符串的子字符串。
equals(Object obj):将此字符串与指定对象进行比较。如果相等,则返回 true;否则返回 false。 indexOf(Stringstr):返回指定子字符串在此字符串中第一次出现的索引。如果没有找到,则返回 -1。 replace(char oldChar, charnewChar):返回一个新的字符串,它是通过用 newChar 替换此字符串中出现的所有 oldChar 得到的。
toLowerCase():使用默认语言环境的规则将此 String 中的所有字符都转换为小写。
toUpperCase():使用默认语言环境的规则将此 String 中的所有字符都转换为大写。
要注意的一点是:由于String对象是不可变的,因此每当我们对一个String对象进行操作时,都会创建一个新的字符串对象。因此,在进行字符串拼接时,建议使用StringBuilder或StringBuffer类来提高效率。
Java中的StringBuffer类
接下来介绍一下StringBuffer类,它是一个可变字符串序列,也就是说,我们可以对它进行添加、插入、删除、修改等操作,使得其内容可以动态地变化。
StringBuffer类的特点
StringBuffer的主要特点如下:
可变性:StringBuffer对象的长度和内容都可以随时改变。
线程安全:StringBuffer的方法是同步的,因此在多线程环境下使用时,不用担心出现线程安全问题。
效率较低:由于StringBuffer是一个线程安全的类,因此它的执行效率要比非线程安全的StringBuilder类略低。
支持链式调用:StringBuffer类的方法支持链式调用,这样可以让代码更加简洁易读。
其方法被synchronized关键字修饰:
StringBuffer类的方法
StringBuffer类提供了一系列的方法,用于对字符串进行操作。其中一些常用的方法如下:
append()方法:用于在字符串末尾添加指定的内容。
insert()方法:用于在字符串的指定位置插入指定的内容。
delete()方法:用于删除字符串中的指定字符序列。
replace()方法:用于替换字符串中的指定字符序列。
reverse()方法:用于将字符串反转。
capacity()方法:用于获取当前对象的容量。
length()方法:用于获取当前对象的长度。
简单介绍下如何使用StringBuffer类拼接字符串:
StringBuffer sb = new StringBuffer();sb.append("Hello");sb.append(" ");sb.append("World!");System.out.println(sb.toString());
上面的代码结果会输出:Hello World!
Java中的StringBuilder类
StringBuilder也是Java中一个可变的字符串类,可以动态地修改字符串内容而无需像普通String类一样创建新的字符串对象。它的主要作用是在字符串操作的过程中,能够更高效地添加、删除和修改字符串内容,特别是在字符串内容经常改变的情况下比String类更加高效。
StringBuilder类特点
StringBuilder具有以下特点:
- 可变性:StringBuilder的长度和内容都可变,可以进行动态修改。
- 线程非安全:由于StringBuilder不是线程安全的,同一时间只能由一个线程访问。
- 高效性:由于StringBuilder的可变性和具有缓存功能,可以有效地减少内存消耗和执行时间。
调用父类的方法,没有被synchronized关键字修饰,多线程下线程不安全:
StringBuilder类方法
StringBuilder提供了一些常见的方法,如append、insert、delete、replace等,可以用于字符串的增、删、改、查等操作。它的方法和StringBuffer类的基本一致,这里就不重复介绍啦。
String,StringBuffer,StringBuilder三者之间的区别
String,StringBuilder和StringBuffer都是Java中用来操作字符串的类,它们之间的主要区别如下:
不可变性方面:
String是不可变的,即一旦创建就不能修改它的值,任何对String对象的修改都将返回一个新的String对象,原有的String对象不会改变。
StringBuilder和StringBuffer是可变的,即在操作时可以修改其实例中的值,而不需要创建新的实例对象。StringBuilder和StringBuffer的主要区别在于线程安全问题:StringBuffer是线程安全的,即多个线程同时操作同一个StringBuffer实例时,不会发生数据混乱的问题,而StringBuilder是非线程安全的,即多线程同时操作同一个StringBuilder实例时,可能会发生数据混乱的问题。
性能方面:
由于字符串是不可变的,每次修改都需要创建新的String对象,这样在频繁的字符串操作时就会导致内存占用大、性能下降等问题。
StringBuilder和StringBuffer在字符串拼接、插入、追加等操作时,都是直接对字符串缓冲区进行修改,所以性能要比String好,而StringBuilder又比StringBuffer性能更优。
线程安全方面:
String是线程安全的,即多个线程可以共享同一个String对象,而不会出现数据冲突的问题。
StringBuilder是非线程安全的,在多线程环境下如果不加锁或者其他同步机制会出现数据混乱问题。
StringBuffer是线程安全的,因为它的所有方法都是synchronized的,所以它在多线程环境下是同步的,不会出现数据冲突问题,但是这也导致StringBuffer的性能相对StringBuilder要差。
Java中的包装类
首先可以思考一个问题,Java中为什么会有包装类?
答案是我们都知道,Java是一门面向对象的语言,Java提供的八种基本数据类型不具备对象的特性(基本数据类型是一种特殊的数据类型,它们存储的是值本身,而不是对象。基本数据类型的变量只能存储一个值。我们不能将基本数据类型的变量作为参数传递给方法或者集合。)因此Java为每个基本数据类型都定义了一个引用类型,即包装类。其对应的关系如下:
Integer:用于表示整数值,对应int
Double:用于表示浮点数值,对应double
Boolean:用于表示布尔值,对应boolean
Character:用于表示字符,对应char
Byte:用于表示字节,对应byte
Short:用于表示短整型数值,对应short
Long:用于表示长整型数值,对应long
Float: 用于表示浮点数,对应float
包装类提供了一些常用的方法,方便我们对基本数据类型进行操作。
例如,Integer类提供了parseInt(String s)方法,可以将一个字符串转换成一个整数;Boolean类提供了valueOf(String s)方法,可以将一个字符串转换成一个布尔值。使用包装类可以使我们的程序更加方便和灵活。
更重要的是,包装类还提供了一个重要的特性,即自动装箱和拆箱。
自动装箱指的是将基本数据类型自动转换成对应的包装类对象;拆箱则是将包装类对象转换成对应的基本数据类型。这样,我们可以直接使用基本数据类型进行运算,而无需手动转换为包装类对象。
//这些包装类可以通过构造函数或静态方法创建。Integer i = new Integer(10);Double d = Double.valueOf("3.14");//我们也可以通过自动装箱和拆箱来实现将基本数据类型与其相应的包装类进行转换:// 自动装箱Integer i = 10;// 自动拆箱int j = i;
万事有利亦有弊,在使用包装类时,我们需要注意:
- 包装类是不可变的。
- 包装类对象之间的比较应该使用equals方法而不是==。
- 在将包装类转换为基本数据类型时,如果包装类对象为null,则会抛出NullPointerException异常。
书籍推荐
深入讲解微服务原理,详尽分析分布式原理,解析面试实战真题,助你快速上手微服务架构。
京东购买链接:点我购买
618,清华社 IT BOOK 多得图书活动开始啦!活动时间为 2023 年 6 月 7 日至 6 月 18 日,清华
社为您精选多款高分好书,涵盖了 C++、Java、Python、前端、后端、数据库、算法与机器学习等多 个 IT
开发领域,适合不同层次的读者。全场 5 折,扫码领券更有优惠哦!快来京东点击链接 IT BOOK
查看详情吧!
粉丝福利:点赞收藏文章,关注博主,任意评论(最多五条),即可参与抽奖。
获奖的欧皇可以49本书中任选一本!!!
文章到这里就先结束了,感兴趣的可以订阅专栏哈,后续会继续分享相关的知识点。