java中的String类(转)

转载:http://blog.csdn.net/koches/article/details/7608139


JAVA字符串格式化-String.format()的使用

String类的format()方法用于创建格式化的字符串以及连接多个字符串对象。熟悉C语言的同学应该记得C语言的sprintf()方法,两者有类似之处。format()方法有两种重载形式。

format(String format, Object... args) 新字符串使用本地语言环境,制定字符串格式和参数生成格式化的新字符串。

format(Locale locale, String format, Object... args) 使用指定的语言环境,制定字符串格式和参数生成格式化的字符串。

显示不同转换符实现不同数据类型到字符串的转换,如图所示。

 

转  换  符

说    明 

示    例

%s

字符串类型

"mingrisoft"

%c

字符类型

'm'

%b

布尔类型

true

%d

整数类型(十进制)

99

%x

整数类型(十六进制)

FF

%o

整数类型(八进制)

77

%f

浮点类型

99.99

%a

十六进制浮点类型

FF.35AE

%e

指数类型

9.38e+5

%g

通用浮点类型(f和e类型中较短的)

 

%h

散列码

 

%%

百分比类型

%n

换行符

 

%tx

日期与时间类型(x代表不同的日期与时间转换符

 

测试用例

复制代码
    public static void main(String[] args) {
        String str=null;
        str=String.format("Hi,%s", "王力");
        System.out.println(str);
        str=String.format("Hi,%s:%s.%s", "王南","王力","王张");          
        System.out.println(str);                         
        System.out.printf("字母a的大写是:%c %n", 'A');
        System.out.printf("3>7的结果是:%b %n", 3>7);
        System.out.printf("100的一半是:%d %n", 100/2);
        System.out.printf("100的16进制数是:%x %n", 100);
        System.out.printf("100的8进制数是:%o %n", 100);
        System.out.printf("50元的书打8.5折扣是:%f 元%n", 50*0.85);
        System.out.printf("上面价格的16进制数是:%a %n", 50*0.85);
        System.out.printf("上面价格的指数表示:%e %n", 50*0.85);
        System.out.printf("上面价格的指数和浮点数结果的长度较短的是:%g %n", 50*0.85);
        System.out.printf("上面的折扣是%d%% %n", 85);
        System.out.printf("字母A的散列码是:%h %n", 'A');
    }
复制代码

以下是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[]); 


整型和字符串相互转换的方法

 

1)将字符串转化为整型

int i = Integer.parseIn(String str);

int i = Integer.valueOf().intValue();

注:Integer.parseIn 和 Integer.valueOf 不同,前者生成的是整型,而后者是一个对象,所以要通过intValue()来获得对象的值;

字串转成 Double, Float, Long 的方法大同小异.


2) 整型转化为字符串

String str = String.valueOf(int i);

String str = Integer.toString(int i);

String str = “” + i ;

注: Double, Float, Long 的方法大同小异.


 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);

 请看如下代码,下面的代码都是针对上面string七种用法而进行一一举例说明:

[java]  view plain  copy
  1. class StringMethodDemo   
  2. {  
  3.  public static void method_Zhuanhuan_Qukong_Bijiao()  
  4.  {  
  5.   String s = "     hello Java    ";  
  6.     
  7.   //打印结果是:(hello和java前后门都有空格)hello java  
  8.   sop(s.toUpperCase());  
  9.   
  10.   //打印结果是:(HELLO和JAVA前后门都有空格)HELLO JAVA  
  11.   sop(s.toLowerCase());  
  12.   
  13.   //打印及结果是:不带空格的“hello java”  
  14.   sop(s.trim());  
  15.   
  16.   //比较数的大写,打印结果是:1,因为b对应ascii值是98,  
  17.   //a对应是97,所以b-a=1  
  18.   String s1 = "abc";  
  19.   String s2 = "aaa";  
  20.   sop(s1.compareTo(s2));  
  21.   
  22.  }  
  23.   
  24.  public static void method_sub()  
  25.  {  
  26.   String s = "abcdef";  
  27.   
  28.   //打印结果是:cdef,从指定位置开始到结尾。如果角标不存在,会出现字符串角标越界。  
  29.   sop(s.substring(2));  
  30.   
  31.   //打印结果是:cd,包含头,不包含尾。  
  32.   sop(s.substring(2,4));  
  33.  }  
  34.  public static void method_split()  
  35.  {  
  36.   String s = "zhangsan,lisi,wangwu";  
  37.   
  38.   String[] arr = s.split(",");  
  39.   
  40.   for(int x=0; x<arr.length; x++)  
  41.   {  
  42.    sop(arr[x]);  
  43.   }  
  44.  }  
  45.   
  46.  public static void method_replace()  
  47.  {  
  48.   String s = "hello java";  
  49.   
  50.   //String s1 = s.replace('a','n');  
  51.   //String s1 = s.replace('w','n');  如果要替换的字符不存在,返回的还是原串  
  52.     
  53.   String s1 = s.replace("java","world");//打印结果是:hello world  
  54.   
  55.   sop("s="+s); //打印结果是:hello java因为字符串一旦被初始化,值就不可被改变  
  56.   sop("s1="+s1);//打印结果是:hello jnvn  
  57.   
  58.  }  
  59.   
  60.  public static void method_trans()  
  61.  {  
  62.   char[] arr = {'a','b','c','d','e','f'};  
  63.   
  64.   String s = new  String(arr,1,3);  
  65.   
  66.   sop("s="+s);//打印结果是:bcd  
  67.   
  68.   String s1 = "zxcvbnm";  
  69.   char[] chs = s1.toCharArray();  
  70.   
  71.   for(int x=0; x<chs.length; x++)  
  72.   {  
  73.    sop("ch="+chs[x]);//打印结果是:ch=z,x,c,v,b,n,m  
  74.   }  
  75.  }  
  76.   
  77.  public static void method_is()  
  78.  {  
  79.   String str = "ArrayDemo.java";  
  80.   
  81.  //判断文件名称是否是Array单词开头  
  82.   sop(str.startsWith("Array"));  
  83.    
  84.  //判断文件名称是否是.java的文件  
  85.   sop(str.endsWith(".java"));  
  86.    
  87.  //判断文件中是否包含Demo  
  88.   sop(str.contains("Demo"));  
  89.  }  
  90.    
  91.   
  92.  public static void method_get()  
  93.  {  
  94.   String str = "abcdeakpf";  
  95.   
  96.   //长度  
  97.   sop(str.length());  
  98.   
  99.   //根据索引获取字符  
  100.   sop(str.charAt(4));  
  101.   //sop(str.charAt(40));当访问到字符串中不存在的角标时会发生StringIndexOutOfBoundsException(字符串角标越界异常)  
  102.   
  103.   //根据字符获取索引  
  104.   //sop(str.indexOf('a'));  
  105.   sop(str.indexOf('a',3));//打印的是5,因为角标3是d,  
  106.         //所以从d后面开始找a,第5个角标是a  
  107.   //sop(str.indexOf('t',3))打印:-1,如果没有找到角标,返回-1  
  108.     
  109.   
  110.   //反向索引一个字符出现的位置(从右往左查找,但是角标还是从左开始)  
  111.   sop(str.lastIndexOf("a"));  
  112.  }  
  113.   
  114.  public static void main(String[] args)   
  115.  {  
  116.    method_Zhuanhuan_Qukong_Bijiao();  
  117.   //method_sub();  
  118.   //method_split();  
  119.   //method_replace();    
  120.   //method_trans();   
  121.   //method_is();  
  122.   //method_get();  
  123.   /* 
  124.   String s1 = "abc"; 
  125.   String s2 = new String("abc"); 
  126.  
  127.   String s3 = "abc"; 
  128.   System.out.println(s1==s2); 
  129.   System.out.println(s1==s3); 
  130.   */  
  131.  }  
  132.   
  133.  public static void sop(Object obj)  
  134.  {  
  135.   System.out.println(obj);  
  136.  }  
  137. }  

最近在论坛上看到关于String s = new String("XYZ") + new String("XYZ");到底创建几个对象的讨论,觉得比较有意思,在此总结一下。

 

在JAVA中除了8种基本类型之外,其他的都是类对象及其引用。所以 "XYZ"在JAVA中是一个String对象,对于String类对象来说它的对象值是不能修改的,也就是具有不变性。

 

但是在下面一段程序中:

[java]  view plain  copy
 print ?
  1. public class TestString {  
  2.     public static void main(String args[]) {  
  3.         String s = "Hello";  
  4.         s = "Java";  
  5.         String s1 = "Java";  
  6.         String s2 = new String("Java");  
  7.         System.out.println(s);  
  8.         System.out.println(s == s1);  
  9.         System.out.println(s == s2);  
  10.     }  
  11. }  
  12. /*output: 
  13.  *Java 
  14.  *true 
  15.  *false 
  16.  */  

打印出s的结果是"Java",看起来s所引用的String变量好像是被修改了,但是如果你了解JVM(Java虚拟机)处理String变量时的机制,你就会知道事实并非如此。

 

在JVM的工作过程中,会创建一片的内存空间专门存入String对象,我们把这片内存空间叫做String池。 

对于语句String s= "Hello";,当JVM看到"Hello"时,会在String池创建String对象存储它,并将它的引用返回给String变量s。

语句s = "Java";,当JVM看到"Java"时,会在String池创建新的String对象存储它,再把新建的String对象的引用返回给String变量s。而原先的String对象"Hello"仍然在String池内,并没有消失,它是不能被修改的。

所以我们仅仅是改变了变量s的引用,而没有改变它所引用的对象,因为String对象的值是不能被修改的。

 

String s1 = "Java";,JVM首先在String池里面看能否找到字符串"Java",如果找到则返回它的引用给s1,否则创建新的String对象,放到String池里。这里由于有s = "Java",所以对象已经被引用,所以依据规则s和s1都是引用同一个对象。所以s==s1返回true。(注: 比较运算符==,对于非基本类型,是比较两引用是否引用内存中的同一个对象)。 

String s2 = new String( "Java");,JVM首先还是在String池里面看能否找到字符串 "Java",如果找到,不做任何事情;否则创建新的String对象,放到String池里面。由于遇到了new关键字,还会在内存上(不是String池里面)创建String对象存储 "Java",并将内存上的(不是String池里面的)String对象返回给s2。所以s==s2将返回false,因为它们引用的不是同一个对象。

 

所以对于语句String s = new String("XYZ") + new String("XYZ");

JVM先在String池中创建一个String对象存储"XYZ",然后由于遇到new关键字,再在内存上创建一个String对象存储"XYZ";

接着由于String池中已经有了"XYZ"的对象,所以第二个new语句不会在String池中创建对象,而只会在内存上创建一个String对象;

最后两个字符串相加会在String池中创建一个String对象"XYZXYZ",并将其引用传给s。

所以总共会创建4个String对象。





java堆与栈 java String分配内存空间(详解)

栈内存

堆内存

基础类型,对象引用( 堆内存地址 )

由new 创建的对象和数组,

存取速度快

相对于栈内存较慢

数据大小声明周期必须确定

分配的内存由java 虚拟机自动垃圾回收器管理。动态分配内存大小

共享特性

栈中如果有字符串,则直接引用

如果没有,开辟新的空间存入值

每new 一次在堆内存中生成一个新的对象。

创建之后值可以改变

String 类声明后则不可改变     

一、栈内存

基础类型 int, short, long, byte, float, double, boolean, char 和对象引用

 

栈的共享特性

String str1 = "abc"; 
String str2 = "abc"; 
System.out.println(str1==str2); //true

1 、编译器先处理String str1 = "abc" ;它会在栈中创建一个变量为str1 的引用,然后查找栈中是否有abc 这个值,如果没找到,就将abc 存放进来,然后将str1 指向abc 。

2 、   接着处理String str2 = "abc"; 在创建完b 的引用变量后,因为在栈中已经有abc 这个值,便将str2 直接指向abc 。这样,就出现了str1 与str2 同时均指向abc 的情况。

二、堆内存

new 、newarray 、anewarray 和multianewarray 等指令建立

   要注意: 我们在使用诸如String str = "abc" ;的格式定义类时,总是想当然地认为,创建了String 类的对象str 。担心陷阱!对象可能并没有被创建!而可能只是指向一个先前已经创建的 对象。只有通过new() 方法才能保证每次都创建一个新的对象。 由于String 类的immutable 性质,当String 变量需要经常变换其值时,应该考虑使用StringBuffer 类,以提高程序效率。

三、  ==   内存地址比对

String str1 = "abc"; 
String str2 = "abc"; 
System.out.println(str1==str2); //true    str1 和str2 同时指向 栈内存 中同一个内存空间

String str3 = "abc"; 
String str4 = new String("abc") ;

System.out.println(str3 == str4);    //flase str3 值在栈内存中,str4 值在堆内存中

 

String hello = "hello" ;

String hel = "hel" ;

String lo = "lo" ;

System.out.println(hello == "hel" + "lo") ; //true

// 两个常量相加,先检测栈内存中是否有hello 如有有,指向已有的栈中的hello 空间

System.out.println(hello == "hel" + lo) ;   //flase

System.out.println(hello == hel + lo) ;     //flase

 //lo 是在常量池中,不检查栈内存,在堆中产生一个新的hello


 

ava堆与栈 java String分配内存空间(详解)

栈内存

堆内存

基础类型,对象引用( 堆内存地址 

由new 创建的对象和数组,

存取速度快

相对于栈内存较慢

数据大小声明周期必须确定

分配的内存由java 虚拟机自动垃圾回收器管理。动态分配内存大小

共享特性

栈中如果有字符串,则直接引用

如果没有,开辟新的空间存入值

每new 一次在堆内存中生成一个新的对象。

创建之后值可以改变

String 类声明后则不可改变     

一、栈内存

基础类型 int, short, long, byte, float, double, boolean, char 和对象引用

 

栈的共享特性

String str1 = "abc"; 
String str2 = "abc"; 
System.out.println(str1==str2); //true

1 、编译器先处理String str1 = "abc" ;它会在栈中创建一个变量为str1 的引用,然后查找栈中是否有abc 这个值,如果没找到,就将abc 存放进来,然后将str1 指向abc 。

2 、   接着处理String str2 = "abc"; 在创建完b 的引用变量后,因为在栈中已经有abc 这个值,便将str2 直接指向abc 。这样,就出现了str1 与str2 同时均指向abc 的情况。

二、堆内存

new 、newarray 、anewarray 和multianewarray 等指令建立

   要注意: 我们在使用诸如String str = "abc" ;的格式定义类时,总是想当然地认为,创建了String 类的对象str 。担心陷阱!对象可能并没有被创建!而可能只是指向一个先前已经创建的 对象。只有通过new() 方法才能保证每次都创建一个新的对象。 由于String 类的immutable 性质,当String 变量需要经常变换其值时,应该考虑使用StringBuffer 类,以提高程序效率。

三、  ==   内存地址比对

String str1 = "abc"; 
String str2 = "abc"; 
System.out.println(str1==str2); //true    str1
 和str2 同时指向 栈内存 中同一个内存空间

String str3 = "abc"; 
String str4 = new String("abc") ;

System.out.println(str3 == str4);    //flase str3 值在栈内存中,str4 值在堆内存中

 

String hello = "hello" ;

String hel = "hel" ;

String lo = "lo" ;

System.out.println(hello == "hel" + "lo") ; //true

// 两个常量相加,先检测栈内存中是否有hello 如有有,指向已有的栈中的hello 空间

System.out.println(hello == "hel" + lo) ;   //flase

System.out.println(hello == hel + lo) ;     //flase

 //lo 是在常量池中,不检查栈内存,在堆中产生一个新的hello

你可能感兴趣的:(java中的String类(转))