Java—解读Java中的String类

String类

Java通过程序中建立String类可以轻松地管理字符串。什么是字符串呢?简单地说,字符串就是一个或多个字符组成的连续序列,程序需要存储的大量文字、字符都使用字符串进行表示、处理。
在这里插入图片描述
Java中定义了String和StringBuffer两个类来封装对字符串的各种操作,它们都被放到了java. lang包中,不需要用import java.lang这个语句导入该包就可以直接使用它们。

String类用于比较两个字符串,查找和抽取串中的字符或子串,进行字符串与其他类型之间的相互转换等。String类对象的内容一旦被初始化就不能再改变,对于String类的每次改变(例如字符串连接等)都会生成一个新的字符串,比较浪费内存。

StringBuffer类用于内容可以改变的字符串,可以将其他各种类型的数据增加、插入到字符串中,也可以转置字符串中原来的内容。一旦通过StringBuffer生成了最终想要的字符串,就应该使用StringBuffer.toString()方法将其转换成String类,随后,就可以使用String类的各种方法操纵这个字符串了。StringBuffer每次都改变自身,不生成新的对象,比较节约内存。

字符串的声明

字符串声明常见方式如下:

String 变量名。
在这里插入图片描述
声明一个字符串对象s1,分配了一个内存空间,没有进行初始化,没有存入任何对象。

s1作为局部变量是不会自动初始化的,必须显式地赋初始值。如果没有赋初始值,在用System. out.println(s1)时会报错。

再看String类

在Java中,用户可以通过创建String类来创建字符串,String对象既可以隐式地创建,也可以显式地创建,具体创建形式取决于字符串在程序中的用法,为了隐式地创建一个字符串,用户只要将字符串字符放在程序中,Java则会自动地创建String对象。

String类的两种实例化方式

  1. 使用字符串常量直接初始化,String 对象名称= “字符串” ;
    在这里插入图片描述
  2. 使用构造方法创建并初始化(public String(String str)),String 对象名称 =new String(“字符串”) ;;
    在这里插入图片描述
    下面通过一个范例来讲解String类实例化方式(NewString.java)。
    在这里插入图片描述
    在这里插入图片描述
    程序第06行使用直接赋值的方式建立并初始化对象,第8行采用构造法创建并初始化对象,第10行采用串联方式产生新的对象,三种方式都完成了String对象的创建及初始化。

对于String对象也可以先声明再赋值。例如:
在这里插入图片描述
构造法也可先建立对象,再赋值。
在这里插入图片描述

String内容的比较

用户经常需要判断两个字符串的大小或相等,比如可能需要判定输入的字符串和程序中另一个编码字符串是否相等。
在这里插入图片描述
1.Java中判定字符串一致的方法有两种。

⑴ 调用equals(object)方法。

string1.equals(string2),比较当前对象(string1)包含的值与参数对象(string2)包含的值是否相等,若相等则equals( )方法返回true,否则返回false,equals( )比较时考虑字符中字符大小写的区别。

equalsIgnoreCase( )可以忽略大小写的进行两个字符串的比较。

在这里插入图片描述
⑵ 使用比较运算符==。

运算符==比较两个对象是否引用同一个实例。
在这里插入图片描述
str1和str3不相等,原因需要结合内存图的分析,首先说明。

① 如果说String是一个类,那么str1一定是这个类的对象,对象名称一定要保存在栈内存之中,那么字符串“Hello”一定保存在堆内存之中;

② 任何情况下使用关键字new都一定会开辟一个新的堆内存空间;

③ String本身是一个类,所以String类的对象是一定可以进行引用传递的,引用传递的最终结果就是不同的栈内存将保存同一块堆内存空间的地址;

④ 栈内存像int型数据,里面保存的是数值,每一个栈内存只能够保存一块堆内存的物理地址数值。

现在可以得出如下的内存关系图。
在这里插入图片描述
根据上例可发现,针对于“==”在本次操作之中实际上是完成了它的相等判断功能,只是它完成的是两个对象的堆内存地址的相等判断,属于地址的数值相等比较,并不是真正意义上的字符串内容的比较。

如果现在要想进行字符串内容的比较,可以使用equals( )。

下面通过一个范例来分析字符串对象相等判断(StringEquals.java)。
在这里插入图片描述
在这里插入图片描述
第08-10行,字符串对象str1和不同方法创建的字符串对象进行一致性判断。

字符串对象str1,str2是不同方法创建的不同对象,内容一致,地址不同,“= =”判断相等是为假, str3和str2引用同一对象,内容一致,地址相同,“==”判断相等为真,由于str1,str2,str3内容相同,用equals( )方法判断相等时,全为true。

  1. Java中判断字符串大小

如果希望知道字符串大小情况,需要调用compareTo( )方法。字符串对象小于给定字符串:compareTo( )方法返回小于零的值;字符串对象等于给定字符串:compareTo( )方法返回小于零的值;字符串对象大于给定字符串:compareTo( )方法返回大于零的值;比较是根据字母顺序,严格来讲是根据字符的ASCII码值进行比较的,返回结果是第一个不同字符ASCII码的差值。

下面通过一个范例来分析字符串对象大小比较(StringCompare.java)。
在这里插入图片描述
在这里插入图片描述
第7~9行,str1通过compareTo( )方法和不同的字符串进行比较,比较的是字符串的内容。

字符串对象str1,compareTo( )运行结果是数值,存放结果的变量的类型定义为int。

str1.compareTo (“That is another string”);中str1和参数字符串前两个字符“Th”相同,“i”的ASCII码为105,“a”的ASCII码为97,结果为第一个不同字符ASCII值的差,result=8。

str1.compareTo(“this is a string”);,str1和参数字符串一致,result1=0。

str1.compareTo(str2);比较时区分大小写,“T”的ASCII码值为84,“t”的ASCII码值为116, result2=-32。

由上知,compareTo( )是按字符串中逐个字符的ASCII码值进行比较。

字符串常量是String类的匿名对象

任何的语言实际上都不会提供字符串类型,但是在Java里面为了简化用户的开发难度,专门提供了String类和使用“"”定义的字符串,但是实际上每一个字符串严格来讲都是String类的匿名对象。

匿名对象的特点:没有名字,而且可以调用类中的相关方法。
在这里插入图片描述
判断某一个用户输入的字符串内容是否等于指定的字符串内容,若采用字符串对象.equals(“内容”)的方式,如果用户没输入字符串,会出现NullPointerException警告,可以采用"字符串".equals(字符串对象)”的方式解决这个问题。
在这里插入图片描述

两种字符串实例化方式的区别

实例化字符串对象可以采用两种方式完成,不同方式在内存中呈现方式不同的分配形式。

  1. 直接赋值方式

如果现在采用直接赋值的形式,那么就好比将一个字符串的常量赋给了指定的字符串变量,而且每一个字符串常量都属于String的匿名对象。
在这里插入图片描述
以直接赋值的方式创建字符串对象str,仅开辟一块堆内存和一块栈内存空间。若采用直接赋值的方式定义多个字符串对象呢?

分析直接赋值法创建字符串时的内存分配(MemmoryAllocation.java)。
在这里插入图片描述
在这里插入图片描述
第05~07行,分析通过直接赋值法和引用传递创建字符串对象strA、strB、strC。

第07行,把strB的地址赋给strC。

第08~10行,strA,strB,strC分别进行“==”比较,并输出结果。

在Java中,若字符串对象使用直接赋值方式完成,如strA,那么首先在第一次定义字符串的时候,会自动的在堆内存之中定义一个新的字符串常量"Hello",如果后面还有其他字符串的对象(如:strB)采用的是直接赋值的方式实例化,并且此内容已经存在,那么就不会开辟新的字符串常量,而是让其指向了已有的字符串内容,即strA,strB指向同一块内存,所以strA == strB比较的结果是true。这样的设计在开发模式上讲称为共享设计模式。
在这里插入图片描述
所谓的共享设计模式指的是在JVM底层(如果是用户自己实现就是依靠动态数组)准备出一个对象池(多个对象),如果现在按照某一个特定方式进行对象实例化的操作,那么此对象的内容会保存到对象池之中,而后如果还有其他的对象也采用了固定的方式声明了与之同样的内容,则此时将不会重新保存新对象到对象池之中,而是从对象池中取出已有的对象内容继续使用,这样一来可以有效的减少垃圾空间的产生。

  1. 构造方法实例化
    在这里插入图片描述
    此时会开辟两块堆内存空间,其中有一块堆内存将成为垃圾,通过构造方法进行的String类对象,也无法进行自动入池的操作,即:数据无法共享。
    在这里插入图片描述
    在String类中提供了一个方法,可以帮助用户手工入池。

手工入池:public String intern();

分析构造方法创建字符串时的内存分配( ConstructorMemmoryAllocation.java)。
在这里插入图片描述
在这里插入图片描述
第04~07行,分析通过直接赋值法和引用传递创建字符串strA,strB,strC,strD。

第05行,用构造法建立strB,并且采用手工入池的方法分配内存。

第08~11行,strA,strB,strC,strD分别进行“==”比较,并输出结果。

String类的对象在实例化时采用不同的方式,开辟的内在空间也不同。

直接赋值:只开辟一块堆内存空间,而且保存的字符串内容可以自动入池,以供其他内容相同的字符串对象使用;

构造方法:开辟两块堆内存空间,有一块将成为垃圾,并且字符串的内容无法自动入池,但是可以使用String类中的intern()方法手工入池。
在这里插入图片描述

字符串一旦声明则不可改变

字符串的内容用户一旦定义,就表示开辟好了指定的空间,那么字符串的内容就不能够被改变了。

下面通过一个范例来分析字符串内容变化情况(StringChange.java)。
在这里插入图片描述
在这里插入图片描述
第06、07行,完成字符串的连接。

程序运行结果显示,字符串str的内容改变了,但事实并非如此。
在这里插入图片描述
由上图可以发现,字符串的内容没有改变,改变的只是String类对象的引用,并且会产生大量字符串垃圾。因此,应该尽量避免出现不断修改字符串内容的现象,以免出现大量垃圾。

String类的常用方法

String是在所有的开发之中最常用的类,所有的程序都会包含字符串的应用,在Java之中,String也定义了大量的操作方法,这些方法全部都在Java Doc文档之中可以查询到。

  1. 字符与字符串

Java延续了编程语言中利用字符数组来表示字符串的特性。一个字符串可以变为一个字符数组,同样,也可以把一个字符数组,变为一个字符串,也可实现从字符串中取出指定位置的字符。
在这里插入图片描述
下面通过一个范例求字符串中指定位置的字符(CharAt.java)。
在这里插入图片描述
在这里插入图片描述
第06、07行,取出字符串中指定位置的字符。

在程序之中,字符串中索引的下标从0开始的,str.charAt(0)取出字符串中第1个字符,即str. charAt(n)取出的是字符串中第n+1个字符。

下面通过一个范例来分析字符串与字符数组互相转换(StringArray.java)。
在这里插入图片描述
在这里插入图片描述
第06行,str.toCharArray( )可以实现将字符串变为字符数组。

第07~11行,字符数组中的数据逐个输出,data.length表示数组中的元素个数。

第13行,new String(data)将字符数组data变为字符串。

第15行,new String(data,5,4)将字符数组中下标为5,即从第6个元素开始取4个字符。

str字符串中的内容是小写字符,同一个字符的小写ASCII码比大写大32,data[x] -= 32完成小写转换成大写。

  1. 字节与字符串

除了提供了字符串与字符的转换操作之外,在String类中也提供了字符串与字节数据的转换操作,可以使用的方法如下所示。
在这里插入图片描述
下面通过一个范例来分析字符串与字节相互转换(StringByte.java)。
在这里插入图片描述
在这里插入图片描述
第06~09行,将byte数组中的内容ASCII码减32。

  1. 字符串查找方法

由一个字符串中若干个字符按顺序形成的连续字符片段,就是字符串的子串。

从一个指定的字符串之中查找某一个子字符串是否存在的操作,称为字符串查找,查找的操作方法如下。
在这里插入图片描述
下面通过一个范例来分析字符串查找方法(StringSearch.java)。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
第06行,str.contains(“hello”)判断字符串str中是否存在子串“hello”。

第09行,str.indexOf(“r”),在字符串str中查找“r”的出现位置索引值。

第12行,str.indexOf(“o”,6),在字符串str中从索引值为6的位置开始查找“o“的出现位置索引值。

第15行,str.lastIndexOf(“w”,12),在字符串str中从索引值12的位置开始由后向前查找“w”出现位置索引值。

第18行,str.startsWith(""),判断字符串str是否以“”开始。

第19行,str.startsWith(" " , 7 ) , 判 断 在 字 符 串 s t r 中 从 索 引 值 为 7 的 位 置 判 断 是 否 以 “ ",7),判断在字符串str中从索引值为7的位置判断是否以“ ",7)str7”开始。

第20行,str.endsWith("##"),判断字符串str是否以“##”结束。

判断字符串中子串是否存在时,返回的是Boolean值,若判断某字符子串出现的位置是,返回子串在字符串中第一次出现位置的索引值,若没找到,则返回-1。

  1. 字符串替换

Java的String类有替换的操作。
在这里插入图片描述
下面通过一个范例来分析字符串替换方法(StringReplace.java)。
在这里插入图片描述
在这里插入图片描述
第06行,str.replaceAll(“o”,"***"),将字符串str中所有“o”出现的位置都用“***”替换。

第07行,str.replaceFirst(“l”,""),将字符串str中第一次出现“l”的位置用“”替换。

可以替换字符串中某一子串,str.replaceAll(“ll”,"***"),则结果是“he***world”。

  1. 字符串截取

从一个指定的字符串中取出里面的部分内容,即子串。从字符串中截取子串方法如下。
在这里插入图片描述
下面通过一个范例来分析字符串中取子串的方法(SubString.java)。
在这里插入图片描述
在这里插入图片描述
第06行,str.substring(5),截取字符串str中索引值从5开始到末尾的子串。

第07行,str.substring(0,5),截取字符串str中索引值从0开始到4结束位置的子串。

字符串中索引值从0开始,substring(int beginIndex, int endIndex),beginIndex表示开始处的索引(包括),endIndex表示结束处的索引(不包括)。截取从指定的位置beginIndex 处开始,一直到索引 endIndex - 1 处的字符。因此,该子字符串的长度为 endIndex-beginIndex。

若str.substring(0,13),会出现IndexOutOfBoundsException错误。取子串时,如果 beginIndex为负,或 endIndex 大于此 String 对象的长度,或 beginIndex大于 endIndex,则出现错误。

  1. 字符串拆分

所谓的字符串拆分,指的是将一个字符串按照指定的字符串regex拆分为若干个字符串,返回的是一个字符型数组,regex不作为任何数组元素的部分返回,操作方法如下。
在这里插入图片描述
下面通过一个范例来分析字符串拆分方法(StringReplace.java)。
在这里插入图片描述
在这里插入图片描述
第06行,str.split(" "),利用空格把str所有字符串的内容拆分成字符串数组元素。

第12行,str.split(" " , 3),利用空格把字符串str内容按从前向后的顺序按空格拆分成3个字符数组元素,即” hello”,” world”,” hello java”。

⑴ 如果用".“作为分隔的话,必须是如下写法:String.split(”\."),这样才能正确地分隔开,不能用String.split(".");
在这里插入图片描述
⑵ 如果用"|“作为分隔的话,必须是如下写法:String.split(”\|"),这样才能正确的分隔开,不能用String.split("|");

⑶ 如果用"“作为分隔,就得写成这样:String.split(”\\"),因为在Java中是用"\“来表示”“的, “.”、”|“和"都是转义字符,必须得加”\";

⑷ 如果在一个字符串中有多个分隔符,可以用"|“作为连接符,比如:str=“acount=8 and uu =45 or n=25”,把三个都分隔出来,可以用Str.split(“and|or”),即用"and"或者"or"进行分隔,分隔结果为"acount=8”," uu=45"," n=25"。

  1. 其他方法

除了以上常见方法外,还有一些方法如下。
在这里插入图片描述
下面通过一个范例来分析常用字符串方法(StringMethod.java)。
在这里插入图片描述
在这里插入图片描述
第06行,str.length()求字符串str的字符个数。

第07行,str.trim().length(),先将字符串str前后空格去掉,再求长度。

第08行,"".isEmpty(),判断字符串""是否为空,true。

第12行,str.concat(“java”),将字符串str的内容和"java"连接在一起。

String.isEmpty()如果string长度为0,返回为true,否则false。

1. String s = new String(“java”);

创建String对象的个数是两个对象,一个是"java",一个是指向"java"的引用对象s。

2. Java中堆内容与栈内存的区别

⑴ 堆内容是栈内存的一个子集。

⑵ 栈内存存取速度仅次于寄存器,栈内存里面的数据可共享,但是其中数据的大小和生存期必须在运行前确定。

⑶ 堆内容是运行时可动态分配的数据区,从速度看比栈内存慢,堆内容里面的数据不共享,大小和生存期都可以在运行时再确定。

⑷ new关键字是运行时在堆内容里面创建对象。每new一次都一定会创建新对象,因为堆数据不共享。

Java—对象的引用与传递

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java,迭代器是一种用于遍历集合或数组元素的对象。它允许你逐个访问集合的每个元素,而不必知道集合的内部实现细节。 Java的迭代器接口是java.util.Iterator。它具有以下方法: 1. hasNext():检查集合是否还有下一个元素。 2. next():返回集合的下一个元素。 3. remove():从集合移除集合的当前元素。 使用迭代器遍历集合的基本步骤如下: 1. 获得集合的迭代器:使用集合的iterator()方法获得迭代器。例如: ``` List<String> myList = new ArrayList<>(); Iterator<String> iterator = myList.iterator(); ``` 2. 遍历集合:使用hasNext()和next()方法逐个访问集合的元素。例如: ``` while (iterator.hasNext()) { String element = iterator.next(); // 处理元素 } ``` 3. 移除元素(可选):使用remove()方法从集合移除当前元素。例如: ``` iterator.remove(); ``` 需要注意的是,不能使用for-each循环来遍历集合并修改元素,因为这会导致ConcurrentModificationException异常。因此,应该使用迭代器的remove()方法来移除元素。 迭代器不仅可以用于遍历Java集合,还可以用于遍历数组。Java的数组迭代器是java.util.ArrayIterator,它具有似于java.util.Iterator的方法。例如: ``` int[] myArray = {1, 2, 3}; Iterator<Integer> iterator = new ArrayIterator<>(myArray); while (iterator.hasNext()) { int element = iterator.next(); // 处理元素 } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值