java8中的字符串的用法

Python09

java8中的字符串的用法,第1张

1. 首先String不属于8种基本数据类型,String是一个对象。因为对象的默认值是null,所以String的默认值也是null;但它又是一种特殊的对象,有其它对象没有的一些特性。2. new String()和new String(“”)都是申明一个新的空字符串,是空串不是null;3. String str=”kvill”;String str=new String (“kvill”)的区别:在这里,我们不谈堆,也不谈栈,只先简单引入常量池这个简单的概念。常量池(constant pool)指的是在编译期被确定,并被保存在已编译的.class文件中的一些数据。它包括了关于类、方法、接口等中的常量,也包括字符串常量。看例1:String s0=”kvill”String s1=”kvill”String s2=”kv” + “ill”System.out.println( s0==s1 )System.out.println( s0==s2 )结果为: true true 首先,我们要知道Java会确保一个字符串常量只有一个拷贝。 因为例子中的s0和s1中的”kvill”都是字符串常量,它们在编译期就被确定了,所以s0==s1为true;而”kv”和”ill”也都是字符串常量,当一个字符串由多个字符串常量连接而成时,它自己肯定也是字符串常量,所以s2也同样在编译期就被解析为一个字符串常量,所以s2也是常量池中 ”kvill”的一个引用。 所以我们得出s0==s1==s2用new String() 创建的字符串不是常量,不能在编译期就确定,所以new String() 创建的字符串不放入常量池中,它们有自己的地址空间。 看例2: String s0=”kvill”String s1=new String(”kvill”)String s2=”kv” + new String(“ill”)System.out.println( s0==s1 )System.out.println( s0==s2 )System.out.println( s1==s2 )结果为: false false false 例2中s0还是常量池中”kvill”的应用,s1因为无法在编译期确定,所以是运行时创建的新对象”kvill”的引用,s2因为有后半部分new String(“ill”)所以也无法在编译期确定,所以也是一个新创建对象”kvill”的应用明白了这些也就知道为何得出此结果了。 4. String.intern(): 再补充介绍一点:存在于.class文件中的常量池,在运行期被JVM装载,并且可以扩充。String的intern()方法就是扩充常量池的一个方法;当一个String实例str调用intern()方法时,Java查找常量池中是否有相同Unicode的字符串常量,如果有,则返回其的引用,如果没有,则在常量池中增加一个Unicode等于str的字符串并返回它的引用;看例3就清楚了 例3: String s0= “kvill”String s1=new String(”kvill”)String s2=new String(“kvill”)System.out.println( s0==s1 )System.out.println( “**********” )s1.intern()s2=s2.intern()//把常量池中“kvill”的引用赋给s2 System.out.println( s0==s1)System.out.println( s0==s1.intern() )System.out.println( s0==s2 )结果为: false ********** false //虽然执行了s1.intern(),但它的返回值没有赋给s1 true //说明s1.intern()返回的是常量池中”kvill”的引用 true 最后我再破除一个错误的理解: 有人说,“使用String.intern()方法则可以将一个String类的保存到一个全局String表中,如果具有相同值的Unicode字符串已经在这个表中,那么该方法返回表中已有字符串的地址,如果在表中没有相同值的字符串,则将自己的地址注册到表中“如果我把他说的这个全局的 String表理解为常量池的话,他的最后一句话,“如果在表中没有相同值的字符串,则将自己的地址注册到表中”是错的: 看例4: String s1=new String("kvill")String s2=s1.intern()System.out.println( s1==s1.intern() )System.out.println( s1+" "+s2 )System.out.println( s2==s1.intern() )结果: false kvill kvill true 在这个类中我们没有声名一个”kvill”常量,所以常量池中一开始是没有”kvill”的,当我们调用s1.intern()后就在常量池中新添加了一个”kvill”常量,原来的不在常量池中的”kvill”仍然存在,也就不是“将自己的地址注册到常量池中”了。 s1==s1.intern()为false说明原来的“kvill”仍然存在; s2现在为常量池中“kvill”的地址,所以有s2==s1.intern()为true。 5. 关于equals()和==: 这个对于String简单来说就是比较两字符串的Unicode序列是否相当,如果相等返回true而==是比较两字符串的地址是否相同,也就是是否是同一个字符串的引用。 6. 关于String是不可变的 这一说又要说很多,大家只要知道String的实例一旦生成就不会再改变了,比如说:String str=”kv”+”ill”+” “+”ans”就是有4个字符串常量,首先”kv”和”ill”生成了”kvill”存在内存中,然后”kvill”又和” “ 生成 ”kvill “存在内存中,最后又和生成了”kvill ans”并把这个字符串的地址赋给了str,就是因为String的“不可变”产生了很多临时变量,这也就是为什么建议用StringBuffer的原因了,因为StringBuffer是可改变的。

String类

String类:

java.lang.String类,不属于8种基本数据类型,String是一个对象,表示字符串常量。

因为对象的默认值是null,所以String的默认值也是null,但它又是一种特殊的对象,有其他对象没有的特性。

new String()和new String("")都是声明一个新的空字符串,是空串不是null。区别:空串是经过new运算符分配了内存,即实际存在了(定义了)。而null则没有(只声明),调用null的字符串的方法会抛出空指针异常。

从根本上认识java.lang.String类和String池。

1、String类是final的,不可被继承。public final class String。

2、String类的本质是字符数组char[],并且其值不可改变。private final char value[]

3、String类对象有个特殊的创建方式,如String x="abc""abc"就表示一个字符串对象,而x是"abc"对象的地址,叫做"abc"引用。

4、Java运行时会维护一个String pool(String池),String池中的字符串内容不可重复,而一般对象(非String类)不存在这个缓冲池,并且创建的对象仅仅用于方法的堆栈区。

5、创建字符串的方式归纳起来有三种:

<1>、使用new关键字创建字符串,String s = new String("abc")

<2>、直接指定,String s = "abc"

<3>、使用串联生成新的字符串,String s = "ab" + "c"

String对象的创建:

1、当使用任何方式来创建一个字符串对象s时,JVM会拿这个s在String池中找是否存在内容相同的字符串对象。如果不存在,则在池中创建一个字符串s,否则,不在池中添加。

2、Java中,只要使用new关键字类创建对象,则一定会(在堆区或栈区)创建一个新对象。

3、使用直接指定或者使用纯字符串串联来创建String对象,则仅仅会检查维护String池中的字符串,池中没有就在池中创建一个,有则直接返回已有的字符串对象地址(引用)。绝不会在堆栈去再创建该String对象。

4、使用包含变量的表达式来创建String对象,则不仅会检查维护String池,而且还会在堆栈区创建一个String对象。

String的不可变性:

不可变字符串具有一个很大的有点:编译器可以把字符串设置为共享。

String类型是不可改变的,比如当你想改变一个String对象时,如:

String s = "abc"

s = "fuck"

JVM不会改变原来的对象("abc"),而是生成一个新的String对象("fuck",当然先检查String池中是否已经有"fuck"字符串对象,有则引用,无则新建),然后让s去指向它,如果原来那个"abc"没有任何对象引用它,虚拟机的垃圾回收机制会接收它。这样可以提高运行效率!

注意:Java中字符串内容的比较用的是专门的方法如equals,compareTo等。==比较的是字符串的引用是否相同。

StringBuffer类:

字符串变量。可修改的字符串序列,该类的对象实体内存空间可以自动改变大小,便于存放一个可变的字符序列。

StringBuffer类有3个构造方法:

StringBuffer()

StringBuffer(int size)

StirngBuffer(String s)

当使用第1个无参数的构造方法时,分配给该对象的实体初始容量可以容纳16个字符,当该扩展字符序列长度>16时,实体容量自动增加以适应新字符串。

当使用第2个构造方法,可以指定分配给该对象的实体的初始容量为参数size指定的字符个数。当对象实体长度>size时自动增加。

当使用第3个构造方法,分配给该对象的实体的初始容量为参数字符串s的长度+16个字符,当对象实体长度大于初始容量时,实体容量自动增加。

StringBuffer对象可以通过length()放发获取实体存放的字符序列长度。通过capacity()方法获取当前实体的实际容量。

StringTokenizer类:

使用java.util.StringTokenizer类,分析一个字符串并分解成可独立使用的单词。

StringTokenizer类有两个常用构造方法:

StringTokenizer(String s):为字符串s构造一个分析器。使用默认的分隔符集合,即空格符(若干个空格符被看做一个空格)、换行符、回车符、Tab符、进纸符(\f)。

StringTokenizer(String s, String dilim):为字符串s构造一个分析器。参数dilim中的字符被作为分隔符。

把StringTokenizer对象称作一个字符串分析器。一个分析器可以使用nextToken()方法逐个获取字符串中的语言符号(单词),每当调用nextToken()时,都将在字符串中获得下一个语言符号,每获得一个语言符号,字符串分析器中负责计数的变量值自动减1,该计数变量的初始值等于字符串中的单词数目(可以用StringTokenizer对象调用countTokens()方法获得计数值)。

如:

String str="we are stud,ents"

StringTokenizer fenxi = new StringTokenizer(str,", ")//使用空格和逗号做分隔符

int count=fenxi.countTokens()

while(fenxi.hasMoreElements())

{

String s = fenxi.nextToken()

System.out.println(s)

}

System.out.println("共有单词:"+count+"个。")

另外,StringTokenizer可以用String类的split函数代替

String str="abcbcdefg"

String[] splitStrs=str.split("")

for(int i=0i<splitStrs.lengthi++)

System.out.println(splitStrs[i])

StringBuilder类StringBuilder类是从 JDK 5 开始新增的,此类提供一个与 StringBuffer 兼容的 API,但不保证同步。该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。与StringBuffer类相比,通常应该优先使用 StringBuilder 类,因为它支持所有相同的操作,但由于它不执行同步,所以速度更快。如果可能,建议优先采用该类,因为在大多数情况中,它比 StringBuffer 要快。注意:将 StringBuilder 的实例用于多个线程是不安全的。如果需要这样的同步,则建议使用 StringBuffer类

首先就要确保他不是null,然后再判断他的长度。

String str = xxx

if(str != null &&str.length() != 0) { }

这种做法是安全的,首先他会判断str是否为空,如果为空那么if就直接退出了,就不会再判断后面的str.length() != 0了,这是JAVA的&&特性,也许其他语言也是这样。

扩展资料:

String字符串判定是否为空方法总结

判断一个字符串str不为空的方法有:

1. str!=null(前提条件)

2. “”.equals(str)

3. str.length()!=0

注意:length是属性,一般集合类对象拥有的属性,取得集合的大小。

例如:数组.length就是取得数组的长度。

length()是方法,一般字符串类对象有该方法,也是取得字符串长度。

例如:字符串.length()

说明: 

1. null表示这个字符串不指向任何的东西,那么没有是否为空的问题,因为引用的实例对象都没有。这时候如果你调用它的方法,那么就会出现空指针异常。

2.”“表示它指向一个长度为0的字符串,这时候调用它的方法是安全的。

3. null不是对象,”“是对象,所以null没有分配空间,”“分配了空间,例如:

String str1 = nullstr引用为空

String str2 = “”str应用一个空串

str1还不是一个实例化的对象,儿str2已经实例化。

对象用equals比较,null用等号比较。

如果str1=null下面的写法错误:

if(str1.equals(“”)||str1==null){ }

正确的写法是 if( ( str1==null ) || str1.equals(“”)){

//先判断是不是对象,如果是,再判断是不是空字符串而且顺序不能乱 }