`

java中String类的用法

 
阅读更多

一、不变模式:

一个字符串对象创建后它的值不能改变。
String str1="hello";//
创建一个对象hello,不会变;
System.out.println(str1);
str1+=" world!";
//两个字符串对象粘粘,系统其实创建了一个新的对象,把Str1的指向改了,指向新的对象;hello                     //变成了垃圾
System.out.println(str1);
//如果一直这样创建会影响系统的效率;要频繁的改变字符串对象的值就用StringBuffer来描述;
StringBuffer sb=new StringBuffer("[");
sb.append("hehe");

sb.append("]");//append();不会制造垃圾,真正在改sb的值;
System.out.println(sb);

二、对象池

 

首先要明白,Object obj = new Object();

obj是对象的引用,它位于栈中, new Object() 才是对象,它位于堆中。

可以这样理解obj是拴在氢气球上的绳子,new Object() 是氢气球,我们通过对象的引用访问对象,就像我们那着绳子氢气球才不会跑掉。

 

 

创建一个Stirng对象,主要就有以下两种方式:

java 代码

  1. String str1 = new String("abc");    
  2. Stirng str2 = "abc";  

     虽然两个语句都是返回一个String对象的引用,但是jvm对两者的处理方式是不一样的。对于第一种,jvm会马上在heap中创建一个String对象,然后将该对象的引用返回给用户。对于第二种,jvm首先会在内部维护的strings pool中通过String equels 方法查找是对象池中是否存放有该String对象,如果有,则返回已有的String对象给用户,而不会在heap中重新创建一个新的String对象;如果对象池中没有该String对象,jvm则在heap中创建新的String对象,将其引用返回给用户,同时将该引用添加至strings pool中。注意:使用第一种方法创建对象时,jvm是不会主动把该对象放到strings pool里面的,除非程序调用Stringintern方法。看下面的例子:

java 代码

  1. String str1 = new String("abc"); //jvm 在堆上创建一个String对象   
  2.   
  3.  //jvm strings pool中找不到值为“abc”的字符串,因此   
  4.  //在堆上创建一个String对象,并将该对象的引用加入至strings pool   
  5.  //此时堆上有两个String对象   
  6. Stirng str2 = "abc";   //并没有创建对象,因为对象池里已经有"abc" 
  7.   
  8.  if(str1 == str2){   
  9.          System.out.println("str1 == str2");   
  10.  }else{   
  11.          System.out.println("str1 != str2");   
  12.  }   
  13.   //打印结果是 str1 != str2,因为它们是堆上两个不同的对象   
  14.   
  15.   String str3 = "abc";   
  16.  //此时,jvm发现strings pool中已有“abc”对象了,因为“abc”equels “abc”   
  17.  //因此直接返回str2指向的对象给str3,也就是说str2str3是指向同一个对象的引用   
  18.   if(str2 == str3){   
  19.          System.out.println("str2 == str3");   
  20.   }else{   
  21.          System.out.println("str2 != str3");   
  22.   }   
  23.  //打印结果为 str2 == str3  

三、String / StringBuffer / StringBuilder 

 

    String类是字符串常量,是不可更改的常量。而StringBuffer是字符串变量,它的对象是可以扩充和修改的。

 

   StringBuffer sb=new StringBuffer("[");//创建StringBuffer对象
   sb.append("hehe");//
hehe加入字符串,变成 "[hehe"

   sb.append("]");//append();不会制造垃圾,真正在改sb的值;
   System.out.println(sb);

   String str = sb.toString();//"[hehe]",赋值给一个字符串对象str

    StringBuilder,一个可变的字符序列。此类提供一个与 StringBuffer 兼容的API,但不保证同步。该类被设计用作StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。如果可能,建议优先采用该类,因为在大多数实现中,它比 StringBuffer 要快。

 

StringBuilder sb=new StringBuilder("[");//创建StringBuilder对象
sb.append("hehe");//
hehe加入字符串,变成 "[hehe"

sb.append("]");//append();不会制造垃圾,真正在改sb的值;
System.out.println(sb);

String str = sb.toString();//"[hehe]",赋值给一个字符串对象str

 

 

四、String类中常用的方法

 

String 类包括的方法可用于检查序列的单个字符、比较字符串、搜索字符串、提取子字符串、创建字符串副本并将所有字符全部转换为大写或小写。不用去记,用到的时候查API,用的多了自然就熟悉了。

 

 

  java.lang.String

 char charAt (int index)

 返回index所指定的字符

 String concat(String str)

 将两字符串连接

 boolean endsWith(String str)

 测试字符串是否以str结尾

 boolean equals(Object obj)

 比较两对象

 char[] getBytes

 将字符串转换成字符数组返回

 char[] getBytes(String str)

 将指定的字符串转成制服数组返回

 boolean startsWith(String str)

 测试字符串是否以str开始

 int length()

 返回字符串的长度

 String replace(char old ,char new)

 oldnew替代

 char[] toCharArray

 将字符串转换成字符数组

 String toLowerCase()

 将字符串内的字符改写成小写

 String toUpperCase()

 将字符串内的字符改写成大写

 String valueOf(Boolean b)

 将布尔方法b的内容用字符串表示

 String valueOf(char ch)

 将字符ch的内容用字符串表示

 String valueOf(int index)

 将数字index的内容用字符串表示

 String valueOf(long l)

 将长整数字l的内容用字符串表示

 String substring(int1,int2)

 取出字符串内第int1位置到int2的字符串

 

view plaincopy to clipboardprint?

  1. import java.util.Collections;   
  2. import java.util.Comparator;   
  3. import java.util.LinkedList;   
  4. import java.util.List;   
  5. public class StringUsage {   
  6.  // 几个欧不太用的方法。   
  7.  public static void main(String[] args) {   
  8.   // 判断字符串首/尾。   
  9.   String contentS = "test String again. test ";   
  10.   System.out.println(contentS);   
  11.   System.out.println("contentS.startsWith(\"test\")\t"  
  12.     + contentS.startsWith("test"));   
  13.   System.out.println("contentS.endsWith(\"test\")\t"  
  14.     + contentS.endsWith("test"));   
  15.   // 忽略大小写的字符串比较方法。   
  16.   System.out   
  17.     .println("contentS.compareToIgnoreCase(contentS.toUpperCase()))\t"  
  18.       + contentS.compareToIgnoreCase(contentS.toUpperCase()));   
  19.   // 不区分大小写的字符串比较。   
  20.   Comparator<String> cmprStr = String.CASE_INSENSITIVE_ORDER;   
  21.   List<String> lstStr = new LinkedList<String>();   
  22.   // 准备数据。   
  23.   lstStr.add("test");   
  24.   lstStr.add("Test");   
  25.   lstStr.add("tEst");   
  26.   lstStr.add("rest");   
  27.   lstStr.add("sest");   
  28.      
  29.   // 不区分大小写的排序。   
  30.   Collections.sort(lstStr, cmprStr);   
  31.   System.out.println(lstStr);   
  32.   // 区分大小写的排序。   
  33.   Collections.sort(lstStr);   
  34.   System.out.println(lstStr);   
  35.   System.out.println("\ntest String.valueOf()");   
  36.      
  37.   //  valueOf 处理 null 对象的字符串转换。   
  38.   try {   
  39.    String ss = null;   
  40.    System.out.println(ss);   
  41.    System.out.println(String.valueOf(null)); // 比较奇怪的地方   
  42.   } catch (RuntimeException e1) {   
  43.       e1.printStackTrace();   
  44.   }   
  45.      
  46.   BigDecimal db = null;   
  47.   try {   
  48.    System.out.println(((BigDecimal)db).toString());   
  49.   } catch (Exception e) {   
  50.    e.printStackTrace();   
  51.   }   
  52.   try {   
  53.    System.out.println(String.valueOf(db));   
  54.   } catch (Exception e) {   
  55.    e.printStackTrace();   
  56.   }   
  57.   db = new BigDecimal("100.00");   
  58.   try {   
  59.    System.out.println(((BigDecimal)db).toString());   
  60.   } catch (Exception e) {   
  61.    e.printStackTrace();   
  62.   }   
  63.  }   
  64. }  

 

五、SCJP题目

 

String a="Hello World!";
String b="Hello World!";
a=b?  a
b是否相等? 为什么?

String a=new String("Hello World!");
String b="Hello World!";
a=b?  a
b是否相等 ? 为什么?

 

解释:

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会确保一个字符串常量只有一个拷贝。  
因为例子中的s0s1中的”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  
2s0还是常量池中”kvill”的应用,s1因为无法在编译期确定,所以是运行时创
建的新对象”kvill”的引用,s2因为有后半部分new String(“ill”)所以也无法在编译
期确定,所以也是一个新创建对象”kvill”的应用;明白了这些也就知道为何得出此结果了。  

4. String.intern()
  
再补充介绍一点:存在于.class文件中的常量池,在运行期被JVM装载,并且可以扩充。Stringintern()方法就是扩充常量池的一个方法;当一个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类的保存到一个全局Strin
g
表中,如果具有相同值的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"常量,所以s1.intern()new String("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是可改变的

分享到:
评论

相关推荐

    java基础String类选择题练习题

    通过这些练习题,学习者可以更好地理解和掌握这两个类的使用方法,为实际编程工作打下坚实的基础。需要注意的是,在实际的学习过程中,除了理论知识外,还需要结合实践操作来进行巩固,这样才能真正掌握这些知识点。

    介绍java中String类的方法

    Java中的String类是编程中非常基础且重要的一个类,它代表不可变的字符序列,即一旦创建...掌握这些基本的String类知识和方法对于Java编程至关重要,它们在日常开发中被广泛应用,理解并熟练运用能提高代码质量和效率。

    java中String类型转换方法.pdf

    Java 中 String 类型转换方法 Java 中 String 类型转换方法是一种常见的编程操作,涉及到各种数据类型之间的转换,包括整型、浮点型、长整型、浮点型等。本文将详细介绍 Java 中 String 类型转换方法的各种形式。 ...

    java中的String类常用方法解析(一)

    在Java编程语言中,`String`类是使用最频繁的类之一,它代表不可变的字符序列。本文将深入解析`String`类的一些常用方法,帮助开发者更好地理解和使用这个核心类。 1. **构造方法** - `String()`:创建一个空字符...

    java string类常用方法

    Java中的String类是Java语言中最基本的类之一,它提供了许多实用的方法来操作字符串。在日常开发中,我们经常会使用这些方法来完成字符串的处理和操作。下面我们将详细介绍Java String类中的常用方法。 charAt方法 ...

    JAVA String.format方法使用介绍

    在JDK1.5中,String类增加了一个非常有用的静态函数format(String format, Objece... argues),可以将各类数据格式化为字符串并输出。其中format参数指定了输出的格式,是最复杂也是最难掌握的一点,而argues则是一...

    Java的String类

    `String`类在Java中扮演着至关重要的角色,其丰富的功能和方法使得处理文本数据变得既方便又高效。理解并熟练掌握`String`类的构造函数和各种操作方法,对于任何Java程序员来说都是必不可少的技能。通过本文的介绍,...

    java自制string类例程

    在Java编程语言中,String类是一个非常基础且重要的部分,它是不可变的,也就是说一旦创建了一个String对象,就...在实际编程中,虽然我们通常使用内置的String类,但这种实践性的学习方式无疑能加深对Java编程的理解。

    JAVA中String类常用方法使用实例.docx

    JAVA 中 String 类常用方法使用实例 在 JAVA 中,String 类是一种常用的类,提供了许多实用的方法来操作字符串和数组。在本文中,我们将介绍 String 类中的常用方法,并通过实例来演示每个方法的使用。 Int length...

    java中String类的知识

    ### Java中String类的知识 #### 一、String 类概述与创建方式 在Java语言中,`String`类是用于表示不可变字符序列的核心类之一。它代表了一个字符串对象,一旦被初始化后,其内容不能被改变。这被称为不可变性...

    深入解析 Java 中的 String 类:特性与使用

    本文将详细探讨 Java 中 String 类的特性及其使用。 Java 中的 String 类提供了丰富的方法和特性,使得字符串的操作变得简单而强大。不可变性、字符串常量池、以及各种字符串操作方法都是 String 类的关键特性。通过...

    java String类常用方法练习小结

    理解并熟练使用`String`类的方法对于Java开发者来说至关重要。通过实践,你可以更好地掌握字符串操作,从而编写出更加高效和优雅的代码。记得在处理字符串时考虑到其不可变性,并根据需要选择合适的方法来完成任务。

    Java的 String 类常用方法大全

    Java 中的 String 类提供了丰富的方法来处理字符串,这些方法可以帮助开发者快速高效地操作字符串。本文将对 Java 的 String 类常用方法进行详细介绍。 一、字符串的替换 Java 中的 String 类提供了三种方法来...

    Java 中 String 类的常用方法

    Java中的String类提供了丰富的字符串操作...以上是Java中String类的一些常用方法,它们是进行字符串操作时的基础工具,每一个方法都根据不同的使用场景来实现相应的功能,从而满足在Java开发中对字符串的各种处理需求。

    java String类的实现

    Java中的`String`类是编程中最常用的类之一,它在Java的`java.lang`包中,无需显式导入即可使用。`String`类代表不可变的字符序列,这意味着一旦创建了`String`对象,它的值就不能改变。这个特性使得`String`在处理...

    java String 使用详解

    Java String 使用详解是 Java 编程语言中最基础也是最重要的一部分,对于 Java 程序员来说,了解 String 类的使用方法是必不可少的。本文将详细介绍 Java String 的使用方法,包括 String 对象的初始化、字符串的...

    深入探讨Java中的String类.pdf

    Java 中的 String 类 Java 中的 String 类是 Java 编程语言中最基本的数据类型之一。String 类是 Java 的一个 final 类,无法被继承。它是 Java 中用于表示字符串的类。Java 中的 String 类有很多特点和用途,本文...

    Java中String类的方法及说明.doc

    这些方法只是String类众多方法中的一部分。String类还提供了其他很多方法,如`startsWith(String prefix)`、`endsWith(String suffix)`、`contains(CharSequence s)`等,用于检查字符串的开头、结尾或包含性。此外,...

Global site tag (gtag.js) - Google Analytics