1、 String类及常用方法
详细讲解了JAVA中最常用的类——String的具体操作,包括字符串的比较,String类的特性,以及String类中一系列方法(包括赋值方法)的使用。
String类
因为String可以直接赋值
String肯定是一个类,如果按之前的理解,一个类要想使用必须使用new开辟空间或者把其他对象的引用传递过来。
String肯定是一个类,如果按之前的理解,一个类要想使用必须使用new开辟空间或者把其他对象的引用传递过来。
String能否采用new的方式赋值呢?我们现在不知道哈~那我们就查下JDK文档
在JavaTM 2 Platform Standard Edition 5.0 API规范中我们在索引查找String
我们看到其有点像整型变量哈,我们继续往下看对象的比较
对象的比较
我们发现str1和str2输出都是abc,但是比较后的结果却是false
别着急哈,我们再定义一个str3,将str2的内容赋值给str3,这样str2和str3同时指向同一个堆内存空间,然后我们再比较str2和str3
我们看下效果哈~
我们发现str2和str3相比是true,为什么?实际上,在这个过程中,我们一起使用的是“==”比较,
在int或其他基本数据类型之中,可以使用“==”进行是否相等的验证,那么在String中,因为String本身虽然可以直接像基本数据类型那样直接赋值,但是其依然要依靠内存的指向。
![java中String类和常用方法的使用 image](https://i-blog.csdnimg.cn/blog_migrate/ebb65493eeb6ca20d27cdec2d521e8d8.png)
· “==”如果直接应用在字符串上进行比较,则表示比较的是内存地址的值。
· 如果要比较字符串里面的内容,则肯定要使用一个方法:此方法为String类的内部提供的一个方法:public booleanequals(String str)
· equals比较两个字符串的内容是否相等的。
如果equals的方法我们不知道,那我们还是查找JDK文档
从上面ooDemo01我们知道String是一个类,那str1、str2及str3就肯定是一个对象,我们可以这样写类似代码str1.equals()来调用equals方法。
我们看下效果,我们发现str1、str2及str3相互比较的话,现在都相等,输出true了
从而我们得到一个结论:
“==”表示比较的是内存地址的值
equals表示比较两个字符串的内容是否相等
“==”表示比较的是内存地址的值
equals表示比较两个字符串的内容是否相等
在面试中经常会问到一个样这样的问题:说明“==”与equals的区别?区别的答案就是上面的结论
String类中的内容一旦声明则不可改变,这句话怎么理解呢?
String有匿名对象—— 字符串
现在我们假设有“abc”这样一个字符串,“abc”就是String的匿名对象。
String有匿名对象—— 字符串
现在我们假设有“abc”这样一个字符串,“abc”就是String的匿名对象。
匿名对象是不是对象呢?我们知道当然是对象,那为什么“abc”就是匿名对象呢?我们看ooDemo03来理解
如果"abc"是一个匿名对象,那我们肯定可以使用"abc".equals(str1)来比较"abc"和str1的内容是否相同,我们看下效果,程序执行输出为true,证明我们的推断“abc”肯定是一个匿名对象。
这样我们就很好理解String str = "abc"是把一个字符串的匿名对象赋值给String的一个对象str。
String类中的内容一旦声明则不可改变,现在我们就来理解这句话,我们来观察以下ooDemo04程序,分析内存,得出String是不可改变的
哈~有人说这可以改变哈~实际上不是这么回事,它根本没有改变,我们来分析下内存操作
String str1="abc";证明栈内存中有个str1,在堆内存中的内容是abc。
str1 +="def"; 首先是先有“def”在堆内存中开辟空间
然后再进行str1 + "def"运算所得的字符串“abcdef”又在堆内存开辟空间
原来str1指向的是“abc”所占的堆内存空间,现在str1 +"def"运算所得的字符串“abcdef”又赋值给str1,所以str1先断开指向“abc”的连接,最后str1就指向“abcdef”新的空间与其建立连接。
总结:虽然以上的显示效果String的内容改变了,但是实际上而言,String改变的只是其内存地址的指向,而其本身的内容没有被改变。所以说我们以后不要这样写代码哈,因为这样影响程序的性能
例如以下一段代码:
我们发现,程序执行效果还是输出了,但是其每一步的运算都要进行内存的转换才能赋值给str1,循环运算100次,那么内存地址引用也要断开重新连接100次,如果次数一多肯定会影响程序性能。
所以以上代码的性能是很差的,因此在开发中坚决不建议这样使用,如果非要有以上的要求,则可以使用另外一个类——
StringBuffer,String的缓冲操作,这个类是可以改变的,这个我们以后再讲
现在我们再来理解
String是JAVA中共享模式的一种应用这句话,这是很多初学者最难理解的部分,我们来看下面一个例子ooDemo06
我们发现str1和str2比较的话是相等的
之前说,只要是字符串就是一个String 的匿名对象吗?但是在String类中如果一个字符串已经明确有了一个对象的指向,则以后其他的String对象如果声明的内容是一样的,则自动指向同一个空间。
我们还是来分析下内存的实际操作
首先是String str1="abc";这个我们现在都理解了
紧接着是String str2="abc";代码,我们可能会想当然的认为在内存操作是这样的
那我们说原来的“abc”有没被引用到,我们知道原来的“abc”已经被str1引用,那么就不可能再生成另外一个“abc”,只会将原来的“abc”地址指向str2,那现在str1和str2都指向同一个内存空间地址,比如“abc”内存空间地址为0x1000,我们进行System.out.println(str1==str2);代码中进行“==”比较时得到的运算结果就是true了,所以说如果内存中已经有相同内容的地址话,我们就不要再开辟新的空间了,如果没有的话,那我们就要重新声明开辟新的空间。
还有一个问题:String类直接赋值和使用new开辟空间有什么区别?该使用那个?
这个问题我们用所说到的知识来分析
直接赋值
如果使用new来赋值
在String str1 = new String("abc");代码中我们知道“abc”是匿名对象,那么在堆内存中就会有块空间是“abc”,紧接着new String("abc")使用new在堆内存中又开辟了一个空间“abc”,最后String str1 = new String("abc");代码将最后生成的“abc”内存地址指向str1,最早的一个“abc”就没使用上。
![java中String类和常用方法的使用 image](https://i-blog.csdnimg.cn/blog_migrate/dd42d2c44c8101ec811087c026fae005.png)
String str1 = new String("abc") ;
会在堆内存中产生两个对象,其中有一个是无用的。
综合以上来说,肯定是直接使用赋值的方式比较合适一些,因为只产生一个对象,而如果使用new关键字开辟,则会产生两个对象。
在对象的比较中,我们还有个问题哈,如何比较两个对象的内容是否相等。
我们定一个这样的要求:
定义一个Person对象,里面包含name和age,产生两个Person对象,如果姓名和年龄相等,则认为两个对象表示的是同一个人。
定义一个Person对象,里面包含name和age,产生两个Person对象,如果姓名和年龄相等,则认为两个对象表示的是同一个人。
我们程序执行下哈~ok,程序显示是同一个人
这样就比较两个对象的内容是否相等。
String作为系统提供好的一个类,在实际开发中有很大的作用,而且String操作方法也很多
1、 求出字符串的长度:
public int length() ;
我们还是来查JDK文档
ok,是34个哈~这样我们就求出字符串的长度了
小的记忆错误:
·数组的长度:数组名称.length 这个没()
·数组的长度:数组名称.length
·字符串的长度:调用的是里面的方法:字符串对象.length() 这个有()
2、将一个字符串变为字符数组:public char[]toCharArray()
确实把字符串一个个拆开转换成数组了
3、将一个字符串按指定的字符分割:public String[] split() ;
这个方法很重要,以后使用会很多
我们看下效果,确实按“:”进行拆分了
4、截取字符串
· public String subString(int beg)
· public String subString(int beg,int end)
· public String subString(int beg)
· public String subString(int beg,int end)
我们现在将定义的字符串
[url]http://redking.blog.51cto.com[/url],让其输出redking.blog.51cto.com字符
ok
如果只让其输出redking呢?
5、替换方法,把一个字符串中的某个指定的字符替换成其他内容
public String replaceAll(String 原字符串,String 要替换的新字符串)
public String replaceAll(String 原字符串,String 要替换的新字符串)
已经替换了
6、去掉左右空格,输入数据的时候常使用
public String trim() ;
去掉左右空格了
7、将所有的字符串变为大写或小写
字符串Michael已经都变为大写和小写了
8、判断一个字符串是否以指定的字符串开头或结尾
· public boolean startsWith(String str):判断是否以str开头
· public boolean endsWith(String str):判断是否以str结尾
· public boolean startsWith(String str):判断是否以str开头
· public boolean endsWith(String str):判断是否以str结尾
9、查找在一个字符串中是否有指定的字符串存在。
public int indexOf(Stringstr):查找在一个字符串中是否包含了str,如果包含了,则返回位置,如果没有查到,则返回-1;
public int indexOf(Stringstr):查找在一个字符串中是否包含了str,如果包含了,则返回位置,如果没有查到,则返回-1;
我们看下实例
我们查下字符串中有没大写的"X"
字符串$_$Michael@_@中没有大写的X哈,所以程序返回-1
那我们来查找下字符串中有没大写的”M“
我们知道字符串中是有大写M的哈,所有下标都是从0开始,所以返回大写“M”其位置3
我们可以利用返回值-1的关键来判断是否查找到要查询的字符串~
验证下,看看效果
我们讲了下String中常用的方法哈,要深入研究就翻翻JDK文档哈~
总结
String类:
· 不可改变,如果要改变,改变的是内存地址的指向
· 两种赋值方式的区别,使用直接赋值
· String的内容比较使用equals,==比较的是内存地址的值
· String中的各种常用方法。
· 不可改变,如果要改变,改变的是内存地址的指向
· 两种赋值方式的区别,使用直接赋值
· String的内容比较使用equals,==比较的是内存地址的值
· String中的各种常用方法。