Java常用API(2)----String类、StringBuffer类、StringBuilder类

一、String类介绍                                                                                                                                           点击此处返回总目录

二、String类的构造方法

三、String类的常用方法

四、String类练习

五、StringBuffer类

六、StringBuffer类的构造方法

七、StringBuffer类的常用方法

八、StringBuffer类练习

九、StringBuilder类

一、String类介绍

        Java当中所有的字符串(用双引号引起来的)都是String类的对象。在Java中,一切都是对象,类是用来描述的对象的。字符串也是对象,String类就是描述字符串对象的。

注意:1 字符串对象的声明:        

              String str = "liupc";                       //String类不用写new,因为这样简单。也可以写成String str = new String("liupc");。

                                                                  //其中:String是类;str是引用类型变量;"liupc"是类的对象。

              String str = new String("liupc");    //使用这种方式时,会在堆上创建两个对象。【例2】

           2 字符串是常量,他们的值在创建之后不能再更改。字符串的本质是一个字符数组。【例1】

           

例1:字符串是常量

package cn.itcast.demo01;

public class Stringdemo {
    public static void main(String[] args) {
        String str = "liupc";          
        str = "aaa";
        System.out.println(str);    //aaa。str是引用类型变量,他是可以再指向另一个字符串的。字符串是常量是指"liupc"不能改变。

                                                 字符串本身是一个对象。"liupc"是一个对象,他是不能改变的。变量的指向变了。

    }
}

为什么字符串是常量?我们看一下String类的实现:

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final char value[];                                  //可以看到字符串的本质是一个一维数组,而且是final的。一旦建立,就不变了。

    /** Cache the hash code for the string */
    private int hash; // Default to 0

    ......

}

例1的内存解释:

步骤一:main()方法入栈。

步骤二:堆里面有个小的区域叫常量池。里面存放了a,b,c....,z,A,B,C,..Z。当执行String str = "liupc"时,首先在堆上从常量池中拿出字符               来用,创建一个字符数组,为{'l','i','u','p','c'}。

步骤三:栈上创建str,指向刚才的字符数组。

步骤四:当指向str="aaa";时,重新创建一个字符数组{'a','a','a'}(不是把{'l','i','u','p','c'}改成{'a','a','a'},而是重新创建)。

步骤五:str指向这个数组。

例2:String str = new String("liupc"); 与String str = "liupc";的不同。

package cn.itcast.demo02;

public class Stringdemo {
    public static void main(String[] args) {
        String str1 = "aaa";      
        String str2 = new String("bbb");
        System.out.println(str1 == str2);                //false。不同的对象。解释见下面的内存分析。
        System.out.println(str1.equals(str1));        //true。比较的是字符串本身。
     
        String str3 = "ccc";
        String str4 = "ccc";
        System.out.println(str3 == str4);                //true。同一个对象。
        System.out.println(str3.equals(str4));        //true。比较的是字符串本身。
        
        String str5 = new String("ddd");
        String str6 = new String("ddd");
        System.out.println(str5 == str6);                //false。不同的对象。解释见下面的内存分析。
        System.out.println(str5.equals(str6));        //true。比较的是字符串本身。
        

    }
}

例2的内存分析:

如上图,左边的例子,当执行String str1 = new String("abc")时,实际上在内存中创建了两个对象。首先"abc"是一个对象,其次new String()又是一个对象。new String()对象中存放的是"abc"对象的地址。然后str1指向new String()对象。

当执行 String str2 = "abc"时,运行时期,虚拟机做了优化,发现内存中有"abc",因此str2指向直接了之前的对象"abc"。

当执行System.out.println(str1 == str2);时,比较的是两个对象的地址,不同,为false。

当执行System.out.println(str1.equals(str2));时,因为String()类对Object类的equals()方法做了重写,所以比较的是字符串。相同为true。

二、String类的构造方法【详见API文档】

1. public String(byte[] bytes)   //通过使用平台的默认字符集解码指定的 byte 数组,构造一个新的 String

                                                 //传递的是字节数组。注意范围。                                            

                                                 //平台指:操作系统。默认字符集指操作系统中的默认编码表。在我们安装的中文版系统里面,默认编                                                      码表是GBK,但是一切编码表都兼容ASCII编码表。

                                                 //将字节数组的每个字节查询编码表得到的结果,来构造字符串。【例1】

                                                 //当为正数是查询的是ASC码表,当为负数时查询的是GBK表。【例2】

2. public String(byte[] bytes, int offset, int length)    //offset表示从第几个开始,length表示有几个字节转成字符串。【例3】

3. public String(char[] value)                                    //将字符数组转成字符串。【例4】

4. public String(char[] value, int offset, int count)     //将字符数组的一部分转化成字符串。【例5】


 例1:

package cn.itcast.demo01;

public class Test {
    public static void main(String[] args) {
        byte[] by = {65,66,67,68};                  //byte数组。字节数是正的,查询ASCII码表。如果是负的,查询GBK表。
        String s = new String(by);                  //调用构造方法。
        System.out.println(s);                        //ABCD。将字节数组的每个字节查询编码表得到的结果,来构造字符串。
    }
}

例2:当字节数组中字节为正数时,查询的是ASCII码表;为负时,查询GBK表。

package cn.itcast.demo03;

public class Test {
    public static void main(String[] args) {
        byte[] by = {-65,-66,-67,-68};           //字节为负,查询的是GBK编码表。要注意两个字节表示一个汉字,所以要写就写偶数个。
        String s = new String(by);
        System.out.println(s);                        //烤郊。
    }
}

例3:将字符数组的一部分转成字符串。

package cn.itcast.demo03;

public class Test {
    public static void main(String[] args) {
        byte[] by = {65,66,67,68};
        String s = new String(by,1,2);             //从66开始的两个字节转成字符串。所以66,67转成字符串。
        System.out.println(s);                         //BC
    }
}

例4:将字符数组转化成字符串。

package cn.itcast.demo03;

public class Test {
    public static void main(String[] args) {
        char[] by = {65,66,67,'吃','D'};
        String s = new String(by);
        System.out.println(s);                           //ABC吃D。
    }
}

例5:将字符数组的一部分转化成字符串。

package cn.itcast.demo03;

public class Test {
    public static void main(String[] args) {
        char[] by = {65,66,67,'吃','D'};
        String s = new String(by,1,3);
        System.out.println(s);                           //BC吃
    }
}

三、String类常用方法【详见API文档】

1.   toString()                   //String类对toString()方法进行了重写,不在是得到对象地址,而是得到字符串的值。【例1】

2.   equals()                     //String类对equals()方法进行了重写,不再是比较对象地址,而是比较字符串。【一、例2】

3.   public boolean equalsIgnoreCase(String anotherString)     //比较两个字符串,忽略大小写【例11】

4.   public int length()     //返回字符串的长度。"liupc"的长度为3。【例2】

5.   public String substring(int beginIndex)     //获取从beginIndex开始的到字符串结尾的字符串。【例3】

6.   public String substring(int beginIndex, int endIndex)    //截取字符串。含第头,不含尾。【例4】

7.   public boolean startsWith(String prefix)    //判断是否以某个字符串为前缀。【例5】

8.   public boolean endsWith(String suffix)      //判断是否以某个字符串为后缀。【例6】

9.   public boolean contains(CharSequence s)  //判断一个字符串是否包含另一个字符串。【例7】

10. public int indexOf(String str)                        //查找一个字符或字符串第一次出现的位置,不存在返回-1。【例8】

11. public byte[] getBytes()                               //将字符串转化为字节数组。【例9】

12. public char[] toCharArray()                          //将字符串转化为字节数组。【例10】

13. public char charAt(int index)                        //返回指定索引处的 char 值。【例12】

14. public String toLowerCase()                       //所有字母都转成小写【例13】

15. public String toUpperCase()                       //所有字母都转成大写【例13】

例1:String类重写了toString()方法。

package cn.itcast.demo01;

public class Test{
    public static void main(String[] args) {
        String str = "liupc";      
        System.out.println(str);   //liupc。toString()方法是Object类的。按照Object类的toString()方法里讲的,当System.out.println()方                                                 法的参数是一个对象时,会自动调用toString()方法。所以这句话相当于System.out.println(str.toString());                                               而toString()方法得到的是对象的地址。这里按道理应该输出对象"liupc"的地址,但是输出的是:liupc。只                                                 有一种情况就是,String类对toString()方法进行了重写。
    }
}

例2:length()的使用

package cn.itcast.demo03;

public class Test {
    public static void main(String[] args) {
        String s = "liu";
        System.out.println(s.length());             //3.
    }
}

例3:字符串截取

package cn.itcast.demo03;

public class Test {
    public static void main(String[] args) {
        String s = "liu";
        System.out.println(s.substring(0));         //"liu"
        System.out.println(s.substring(1));         //"iu"
        System.out.println(s.substring(3));         //"",即空字符串。
        //System.out.println(s.substring(4));       //java.lang.StringIndexOutOfBoundsException
    }
}

例4:字符串截取。

package cn.itcast.demo03;

public class Test {
    public static void main(String[] args) {
        String s = "liupc";
        System.out.println(s.substring(1,3));        //"iu"。包含头,不包含尾。
    }
}

例5:判断是否以一个字符串开始

package cn.itcast.demo03;

public class Test {
    public static void main(String[] args) {
        String s = "liupc";
        System.out.println(s.startsWith("li"));       //true
        System.out.println(s.startsWith("i"));        //false
    }
}

例6:判断字符串的后缀是不是另一个字符串

package cn.itcast.demo03;

public class Test {
    public static void main(String[] args) {
        String s = "liupc";
        System.out.println(s.endsWith("pc"));    //true
        System.out.println(s.startsWith("i"));      //false
    }
}

例7:判断是否包含另一个字符串

package cn.itcast.demo03;

public class Test {
    public static void main(String[] args) {
        String s = "liupc";
        System.out.println(s.contains("up"));    //true
        System.out.println(s.contains("ip"));     //false
    }
}

例8:查找一个字符或字符串第一次出现的位置。

package cn.itcast.demo03;

public class Test {
    public static void main(String[] args) {
        String s = "liui";
        System.out.println(s.indexOf("iu"));      //1
        System.out.println(s.indexOf('i'));         //1。第一个出现的位置。
        System.out.println(s.indexOf("pc"));     //-1。找不到显示-1。
    }
}

例9:将字符串转化为字节数组

package cn.itcast.demo03;

public class Test {
    public static void main(String[] args) {
        String s = "烤郊";
        byte[] by  =s.getBytes();
        for(int i = 0;i<by.length;i++){
            if(i == by.length -1){
                System.out.println(by[i]);
            }else{
                System.out.print(by[i]+",");     //-65,-66,-67,-68
            }
        }
    }
}

例10:将字符串转化为字符数组。

package cn.itcast.demo03;

public class Test {
    public static void main(String[] args) {
        String s = "烤郊";
        char[] by  =s.toCharArray();
        for(int i = 0;i<by.length;i++){
            if(i == by.length -1){
                System.out.println(by[i]);
            }else{
                System.out.print(by[i]+",");     //烤,郊
            }
        }
    }
}

例11:比较两个字符串是否相等,忽略大小写

package cn.itcast.demo03;

public class Test {
    public static void main(String[] args) {
        String str1 = "Abcd";
        String str2 = "aBcD";
        
        System.out.println(str1.equalsIgnoreCase(str2));  //true
    }
}

例12:返回指定索引处的 char

package cn.itcast.demo03;

public class Test {
    public static void main(String[] args) {
        String str1 = "Abcd";
        System.out.println(str1.charAt(2));  //c
    }
}

例13:转化成大写或小写

package cn.itcast.demo03;

public class Test {
    public static void main(String[] args) {
        String str1 = "AbcD";
        System.out.println(str1.toLowerCase());  //abcd
        System.out.println(str1.toUpperCase());  //ABCD
    }
}

四、String类练习

练习1:获取指定字符串中,大写字母、小写字母、数字的个数。

package cn.itcast.demo04;

public class Count {
    public static void main(String[] args) {
        String str = "abc12ABCD";
        int count1 = 0;
        int count2 = 0;
        int count3 = 0;
        char ch = ' ';
        
        for(int i = 0;i<str.length();i++){
            ch = str.charAt(i);
            if(ch <= '9' && ch>= '0'){
                count1++;
            }else if(ch<='z' && ch>='a'){
                count2++;
            }else if(ch<='Z' && ch>='A'){
                count3++;
            }
        }
        System.out.println("数字个数:"+count1);              //数字个数:2
        System.out.println("小写字母个数:"+count2);       //小写字母个数:3
        System.out.println("大写字母个数:"+count3);       //大写字母个数:4
    }
}

练习2:将字符串中,第一个字母转换成大写,其他字母转换成小写,并打印改变后的字符串。(假设全是字母)

package cn.itcast.demo05;

public class Convert {
    public static void main(String[] args) {
        System.out.println(convert("bbCdd"));     //Bbcdd
        System.out.println(convert("CddEe"));     //Cddee
    }
    
    public static String convert(String str){
        return (str.substring(0, 1).toUpperCase()+str.substring(1).toLowerCase());
    }
}

练习3:查询大字符串中,出现指定小字符串的次数。如“hellojava,nihaojava,javazhenbang”中查询出现“java”的次数。

package cn.itcast.demo06;

public class Conut {
    public static void main(String[] args) {
        System.out.println(count("liupcaa,liupcbb,liupccc","liupc"));            //3
        System.out.println(count("aaaaaa","aa"));                                       //3
        StringBuffer b ;
    }
    
    public static int count(String str1, String str2){
        int count = 0;
        int index;
        while((index = str1.indexOf(str2))!=-1){
            count ++;
            str1 = str1.substring(index+str2.length());
        }
        return count;
    }
}

五、StringBuffer类

String类虽然功能很强大,但是有一个弱点,就是String类是不可变的,一旦定义好之后就不可变了,这样会造成内存浪费问题。所以,JDK为了解决字符串的内存问题,开发了StringBuffer类,即字符串缓冲区类,他的出现目的就是为了提高字符串的操作效率。

查看StringBuffer的内部实现,为char[] value 。与String类一样,也是一个字符数组,但是他前面没有final修饰,所以是可以改变的。

六、StringBuffer类的构造函数

1. public StringBuffer()    //构造一个其中不带字符的字符串缓冲区,初始容量为 16 个字符。

2. public StringBuffer(String str)    //构造一个字符串缓冲区,并将其内容初始化为指定的字符串内容。

七、StringBuffer类常用的函数

1. public StringBuffer append(Object obj)          //将任意对象添加到字符串缓冲区中。【例1】

2. public StringBuffer delete(int start, int end)    //删除指定范围内的数据。含头不含尾。[start,end)【例2】

3. public StringBuffer insert(int offset, Object obj)   //在offset的位置上,插入任意对象的数据。注意不是在offset之后插入。【例3】

4. public StringBuffer replace(int start, int end, String str)     //将[start,end)的字符替换成str。【例4】

5. public StringBuffer reverse()                                             //将缓冲区的字符反转。【例5】

6. public String toString()                                    //对toString()进行了重写。将可变的缓冲区对象转换为不可变的字符串对象。【例6】

例1:append追加

package cn.itcast.demo08;

public class Test {
    public static void main(String[] args) {
        StringBuffer s = new StringBuffer();
        s.append("aa").append(12).append(true);   
        System.out.println(s);                                    //aa12true
    }
}

例2:删除指定范围内的数据

package cn.itcast.demo08;

public class Test {
    public static void main(String[] args) {
        StringBuffer s = new StringBuffer("liupc");
        s.delete(1, 3);
        System.out.println(s);                  //lpc
        
        s.delete(0, s.length());                //如何删除所有的数据
        System.out.println(s);                  //""
    }
}

例3: 在索引的位置上插入数据

package cn.itcast.demo08;

public class Test {
    public static void main(String[] args) {
        StringBuffer s = new StringBuffer("liu");
        s.insert(1,"bc");
        System.out.println(s);    //lbciu
    }
}

例4:替换

package cn.itcast.demo08;

public class Test {
    public static void main(String[] args) {
        StringBuffer s = new StringBuffer("liupc");
        s.replace(1, 3, "aa");
        System.out.println(s);    //laapc
    }
}

例5:将缓冲区的字符反转。

package cn.itcast.demo08;

public class Test {
    public static void main(String[] args) {
        StringBuffer s = new StringBuffer("liupc");
        s.reverse();
        System.out.println(s);    //cpuil
    }
}

例6:将缓冲区的所有字符转换成字符串。

package cn.itcast.demo08;

public class Test {
    public static void main(String[] args) {
        StringBuffer s = new StringBuffer("liupc");
        String str = s.toString();
        System.out.println(str);    //liupc
    }
}

八、StringBuffer类练习

练习:将一个数组int[] arr= {12,13,14}转化成字符串"[12,13,14]"。

package cn.itcast.demo07;

public class Test {
    public static void main(String[] args) {
        int a[] = {12,3,4,56,7};
        StringBuilder s = new StringBuilder();
        s.append("[");
        for(int i = 0 ;i<a.length;i++){
            if(i == a.length-1){
                s.append(a[i]).append("]");
            }else{
                s.append(a[i]).append(",");
            }
        }
        System.out.println(s);             //[12,3,4,56,7]
    }
}

九、StringBuilder类

StringBulider类中的方法与StringBuffer中的方法完全一样。区别是,StringBuilder类是线程不安全的类,而StringBuffer类是线程安全的类。安全意味着运行速度慢。

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

猜你喜欢

转载自blog.csdn.net/pengchengliu/article/details/81567155