继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

Java中String的用法总结

_慎独i
关注TA
已关注
手记 13
粉丝 12
获赞 641

以下是string的七种用法,注意哦,记得要时常去查看java的API文档,那个里面也有很详细的介绍

1>获取
1.1:字符串中包含的字符数,也就是字符串的长度。
int length():获取长度
1.2:根据位置获取位置上某个字符。
char charAt(int index)
1.3:根据字符获取该字符在字符串中的位置。
int indexOf(int ch):返回的是ch在字符串中第一次出现的位置。
int indexOf(int ch,int fromIndex):从fromIndex指定位置开始,获取ch在字符串中出现的位置。

int indexOf(String str):返回的是str在字符串中第一次出现的位置。
int indexOf(String str,int fromIndex):从fromIndex指定位置开始,获取str在字符串中出现的位置。
1.4:int lastIndexOf(String str):反向索引。

2>判断
2.1:字符串中是否包含某一个子串。
boolean contains(str);
特殊之处:indexOf(str):可以索引str第一次出现为止,如果返回-1,表示该str不在字符串中存在。
所以,也可以用于对指定判断是否包含。
if(str.indexOf("a")!=1)

   而且该方法既可以判断,也可以获取出现的位置。

2.2:字符串中是否有内容。
boolean isEmpty():原理就是判断长度是否为0。
2.3:字符串是否以指定内容开头。
boolean startsWith(str);
2.4:字符串是否以指定内容结尾。
boolean endsWith(str);
2.5:判断字符内容是否相同,复写了object类中的equals方法。
boolean equals(str);
2.6:判断内容是否相同,并忽略大小写。
boolean.equalsIgnorecase();

3>转换
3.1:将字符数组转成字符串。
构造函数:String(char[])
String(char[],offset,count):将字符数组中的一部分转成字符串
静态方法:
static String copyValueOf(char[]);
static String copyValueOf(char[] data,int offset,int count);

 static String valueOf(char[]); 

3.2:将字符串转成字符组
char[] tocharArray();

3.3:将字节数组转成字符串。
String(byte[])
String(byte[],offset,count):将字节数组中的一部分转成字符串
3.4:将字符串转成字节数组。
byte[] getBytes()

3.5:将基本数据类型转成字符串,
static String valueOf(int)
static String valueOf(double)

// 3+"" 与 String.valueOf(3)的值是一样的
特殊:字符串和字节数组在转换过程中,是可以指定编码的。

4>替换
String replace(oldchar,newchar);

5>切割
String[] split(regex);

6>子串。获取字符串中的而一部分
String subString(begin);
String subString(begin,end);

7>转换,去除空格,比较。
7.1:将字符串转成大写或小写
String toUpperCsae() 大转小
String toLowerCsae() 小转大

7.2:将字符串两端的多个空格去除
String trim();

7.3:对两个字符串进行自然顺序的比较
int compareTo(string);

示例演示:

class StringMethodDemo   
{  
 public static void method_Zhuanhuan_Qukong_Bijiao()  
 {  
  String s = "     hello Java    ";  

  //打印结果是:(hello和java前后门都有空格)hello java  
  sop(s.toUpperCase());  

  //打印结果是:(HELLO和JAVA前后门都有空格)HELLO JAVA  
  sop(s.toLowerCase());  

  //打印及结果是:不带空格的“hello java”  
  sop(s.trim());  

  //比较数的大写,打印结果是:1,因为b对应ascii值是98,  
  //a对应是97,所以b-a=1  
  String s1 = "abc";  
  String s2 = "aaa";  
  sop(s1.compareTo(s2));  

 }  

 public static void method_sub()  
 {  
  String s = "abcdef";  

  //打印结果是:cdef,从指定位置开始到结尾。如果角标不存在,会出现字符串角标越界。  
  sop(s.substring(2));  

  //打印结果是:cd,包含头,不包含尾。  
  sop(s.substring(2,4));  
 }  
 public static void method_split()  
 {  
  String s = "zhangsan,lisi,wangwu";  

  String[] arr = s.split(",");  

  for(int x=0; x<arr.length; x++)  
  {  
   sop(arr[x]);  
  }  
 }  

 public static void method_replace()  
 {  
  String s = "hello java";  

  //String s1 = s.replace('a','n');  
  //String s1 = s.replace('w','n');  如果要替换的字符不存在,返回的还是原串  

  String s1 = s.replace("java","world");//打印结果是:hello world  

  sop("s="+s); //打印结果是:hello java因为字符串一旦被初始化,值就不可被改变  
  sop("s1="+s1);//打印结果是:hello jnvn  

 }  

 public static void method_trans()  
 {  
  char[] arr = {'a','b','c','d','e','f'};  

  String s = new  String(arr,1,3);  

  sop("s="+s);//打印结果是:bcd  

  String s1 = "zxcvbnm";  
  char[] chs = s1.toCharArray();  

  for(int x=0; x<chs.length; x++)  
  {  
   sop("ch="+chs[x]);//打印结果是:ch=z,x,c,v,b,n,m  
  }  
 }  

 public static void method_is()  
 {  
  String str = "ArrayDemo.java";  

 //判断文件名称是否是Array单词开头  
  sop(str.startsWith("Array"));  

 //判断文件名称是否是.java的文件  
  sop(str.endsWith(".java"));  

 //判断文件中是否包含Demo  
  sop(str.contains("Demo"));  
 }  

 public static void method_get()  
 {  
  String str = "abcdeakpf";  

  //长度  
  sop(str.length());  

  //根据索引获取字符  
  sop(str.charAt(4));  
  //sop(str.charAt(40));当访问到字符串中不存在的角标时会发生StringIndexOutOfBoundsException(字符串角标越界异常)  

  //根据字符获取索引  
  //sop(str.indexOf('a'));  
  sop(str.indexOf('a',3));//打印的是5,因为角标3是d,  
        //所以从d后面开始找a,第5个角标是a  
  //sop(str.indexOf('t',3))打印:-1,如果没有找到角标,返回-1  

  //反向索引一个字符出现的位置(从右往左查找,但是角标还是从左开始)  
  sop(str.lastIndexOf("a"));  
 }  

 public static void main(String[] args)   
 {  
   method_Zhuanhuan_Qukong_Bijiao();  
  //method_sub();  
  //method_split();  
  //method_replace();    
  //method_trans();   
  //method_is();  
  //method_get();  
  /* 
  String s1 = "abc"; 
  String s2 = new String("abc"); 

  String s3 = "abc"; 
  System.out.println(s1==s2); 
  System.out.println(s1==s3); 
  */  
 }  

 public static void sop(Object obj)  
 {  
  System.out.println(obj);  
 }  
}  

全面理解::

  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 str ;
如果说str是null,那么内存根本没创建字符串对像,并由str引用。
如果说str是空串,那么确实存在一个由str引用的字符串对像,只不过这个字符串的值是""

null用来表示一个引用没有实例存在,而""本身是一个实例,有自己的对象空间,和"zzyyxx"这样的String没什么区别。两个都是有值 !!!

其次需要注意,当oracle 字段里面的值为空时,从oracle读出来的是字符串"null"(可能是程序读出来的时,将空对象转换成为了字符串“null”)。

还有URL得参数时如:oylin.jsp?id=<%=id%>,当id为空对象是,有可能也将空对象转换成为了字符串“null”,在写程序的时候要多加注意。

其实是request.getParameter(username),也许可能会出现这类情况,还有待进一步了解,暂时留个记号

另一个问题就是String的null或空值的判断处理:有以下两种方法
f (name != null && !name.equals("")) {
//do something
}

    或者

   if (!"".equals(name)) {//将""写在前头,这样,不管name是否为null,都不会出错。
           //do something
     }
打开App,阅读手记
17人推荐
发表评论
随时随地看视频慕课网APP

热门评论

不要误导大家,String s1=new String("kvill"); 这里"kvill"在new之前就已经声明了"kvill"这个字符串常量了,编译期调用String构造方法前就已经有kvill了,new String(new char[]{'k','v','i','l','l'})这样声明才没有在调用构造方法前声明这个字符串,结果就不一样了

不要误导大家,String s1=new String("kvill"); 这里"kvill"在new之前就已经声明了"kvill"这个字符串常量了,编译期调用String构造方法前就已经有kvill了,new String(new char[]{'k','v','i','l','l'})这样声明才没有在调用构造方法前声明这个字符串,结果就不一样了

查看全部评论