java-String类

-------------------------------------

一,String类的特点

  1,字符串都是对象。
  2,一旦初始化就不可以被更改。因为是常量。因此是可以共享的.(String s2 = "itca";String s1= "itc";可以这样定义的,两个指同一个)
  3,通过String类的构造函数可以知道,将字节数组或者字符转成字符串。

package string;

public class StringDemo {

    /**
     * @param args
     */
    public static void main(String[] args) {
        
        //定义一个字符串。
        String str = "abcd";  
//        str = "haha"; //这里的和上面的已经不同了,此时内存里有"abcd"和"haha";前者并没有消失;
        System.out.println("str="+str);

        
        //---------------
        System.out.println("-------多个引用指向同一个字符串--------");
        String s1 = "itcast";
        String s2 = "itcast";
        System.out.println(s1==s2);//这里的结果是true;s1和s2指向同一个,这样做是为了节省内存
        
        System.out.println("-------两个内容相同,创建方式不同的字符串,面试题--------");
        String s3 = "abc";
        String s4 = new String("abc");
        
        //s3和s4有什么不同呢?
        /*
         * s3创建,在内存中只有一个对象。//"abc"是一个对象
         * 
         * s4创建,在内存中有两个对象。// "new"关键字是一个对象,里面的"abc"是一个对象;
         */
        
        System.out.println(s3==s4);//false
//        因为String复写了equals方法,
//        建立字符串自己的判断相同的依据。通过字符串对象中的内容来判断的。
        System.out.println(s3.equals(s4));//true,
        
    }

}

 -------------------------------------

二,String-字符串方法查找

package string;

public class StringDemo2 {

    /**
     * @param args
     */
    public static void main(String[] args) {
        /*
         * "abcde"
         * 
         * 1,字符串是一个对象,那么它的方法必然时围绕操作这个对象的数据而定义的。
         * 2,你认为字符串中有哪些功能呢?
         *     2.1 有多少个字符?
         *         int length()
         * 
         *     2.2 字符的位置。
         *         int indexOf(ch,fromIndex);  //查找的中心思想:1,先找返回值类型,2,在找需要传的参数,
         * 
         *     2.3 获取指定位置上的字符。
         *         char charAt(int)
         * 
         *  2.4 获取部分字符串。
         *      String substring(int start,int end);
         *  
         * 
         * 
         */
        String str = "abada";
//        System.out.println("length="+str.length());
        int len = str.length();
        System.out.println("len="+len);
        
        //------a字母出现的位置------
        int index = str.indexOf('a');//获取的是a字符第一次出现的位置。
        System.out.println("index="+index);
        //------第二个a字母出现的位置------
        
        int index1 = str.indexOf('a',index+1);
        System.out.println("index1="+index1);
        //------第三个a字母出现的位置------
        int index2 = str.indexOf('a',index1+1);
        System.out.println("index2="+index2);
        
        str = "sdfghjkl;wertyuiop[sdfghjkla;";
        int index3 = str.lastIndexOf('m');//如果要找的字符不存在,-1
        System.out.println("index3="+index3);
        
        //----------获取指定位置上字符。---------------
        str = "itcast";
        char ch = str.charAt(3);//不存在角标会发生StringIndexOutOfBoundsException
        System.out.println("ch="+ch);
        
        //------------获取部分字符串----------------------
        String s = str.substring(2, 4);//包含头,不包含尾。
        System.out.println("s="+s);
        
    }

}

  -------------------------------------

三,字符串数组排序

package string;

import java.util.Arrays;

public class StringTest2_1 {

    /**
     * main函数
     * @param args
     */
    public static void main(String[] args) {
    
        /*
         * 案例一:字符串数组
         * ["abc","nba","cctv","itcast"]
         * 要求从小到大排序。
         * 
         */
        String[] strs = {"abc","nba","cctv","itcast"};
        printArray(strs);
        sortString(strs);
        printArray(strs);
        

    }

    

    /**
     * 字符串数组
     * 思路:
     * 1,曾经玩过int[]排序,选择,冒泡。
     * 2,字符串排序同理。
     * 3,for嵌套循环。
     * 4,循环中进行元素的大小比较,满足条件位置置换。
     * @param strs
     */
    public static void sortString(String[] strs) {
        
        for (int i = 0; i < strs.length -1 ; i++) {
            for (int j = i + 1; j < strs.length; j++) {
                if(strs[i].compareTo(strs[j])>0){//对象比较用方法。compareTo。
                    swap(strs,i,j);
                }
            }
        }
//        Arrays.sort(strs); 这个也是可以用的;
        
    }
    /*
     * 数组元素位置置换。
     */
    private static void swap(String[] strs, int i, int j) {
        String temp = strs[i];
        strs[i] = strs[j];
        strs[j] = temp;
        
    }
    /*
     * 打印字符串数组。
     */
    private static void printArray(String[] strs) {
        for (int i = 0; i < strs.length; i++) {
            System.out.print(strs[i]+" ");
        }
        System.out.println();
    }
}

-------------------------------------

四,字符串出现的次数

package  string;

public class StringTest2_2 {

    /**
     * @param args
     */
    public static void main(String[] args) {
        
        /*
         * 
         * 案例二:
         * "witcasteritcasttyuiitcastodfghjitcast"有几个itcast
         * 
         * 思路:
         * 1,无非就是在一个字符串中查找另一个字符串。indexOf。
         * 2,查找到第一次出现的指定字符串后,如何查找第二个呢?
         * 3,无需在从头开始,只要从第一次出现的位置+要找的字符串的长度的位置开始向后查找下一个第一次出现的位置即可。
         * 4,当返回的位置是-1时,查找结束。
         */
        String str = "witcasteritcasttyuiitcastodfghjitcast";
        String key = "itcast";
        
        int count = getKeyCount(str,key);
        System.out.println("count="+count);
        /*
        int x = str.indexOf(key,0);//从头开始找。
        System.out.println("x="+x);
         
        int y = str.indexOf(key,x+key.length());//从指定起始位开始找。
        System.out.println("y="+y);
        
        int z = str.indexOf(key,y+key.length());//从指定起始位开始找。//这是刚开始的思路
        System.out.println("z="+z);
        
        int a = str.indexOf(key,z+key.length());//从指定起始位开始找。
        System.out.println("a="+a);
        
        int b = str.indexOf(key,a+key.length());//从指定起始位开始找。
        System.out.println("b="+b);
        */
    }

    /**
     * 获取key在str中出现次数。
     * @param str
     * @param key
     * @return
     */
    public static int getKeyCount(String str, String key) {
        
        //1,定义变量。记录每一次找到的key的位置。
        int index = 0;
        //2,定义变量,记录出现的次数。
        int count = 0;
        
        //3,定义循环。只要索引到的位置不是-1,继续查找。
        while((index = str.indexOf(key,index))!=-1){
            
            //每循环一次,就要明确下一次查找的起始位置。
            index = index + key.length();
            
            //每查找一次,count自增。
            count++;
        }
        return count;
    }

}

 -------------------------------------

五,按照长度递减获得字符串(重点理解)

package string;

public class StringTest2_3 {

    /**
     * @param args
     */
    public static void main(String[] args) {
        /*
         * 
         * 
         * 案例三: "itcast_sh"要求,将该字符串按照长度由长到短打印出来。 itcast_sh itcast_s tcast_sh
         */

        String str = "itcast";
        printStringByLength(str);

    }
    //这是个三角形的问题,像九九乘法口口诀
    public static void printStringByLength(String str) {

        // 1,通过分析,发现是for嵌套循环。
        for (int i = 0; i < str.length(); i++) {//控制行数

            for (int start = 0, end = str.length() - i; end <= str.length(); start++, end++) {  //控制列数

                //根据start,end截取字符串。
                String temp = str.substring(start, end);
                System.out.println(temp);
            }

        }

    }

}

测试结果

java-String类

原理图

java-String类

 -------------------------------------

六,Stringbuffer-基本使用

package cn.itcast.api.stringbuffer;

public class StringBufferDemo {

    /**
     * @param args
     */
    public static void main(String[] args) {
        /*
         * StringBuffer:
         * 1,是一个字符串缓冲区,其实就是一个容器。
         * 2,长度是可变,任意类型都行。注意:是将任意数据都转成字符串进行存储。
         * 3,容器对象提供很多对容器中数据的操作功能,比如:添加,删除,查找,修改。
         * 4,必须所有的数据最终变成一个字符串。
         * 和数组最大的不同就是:数组存储完可以单独操作每一个元素,每一个元素都是独立的。
         * 字符串缓冲区,所有存储的元素都被转成字符串,而且最后拼成了一个大的字符串。
         * 
         * 可变长度数组的原理:新建数组,并复制数组元素到新数组中*/

        //1,创建一个字符串缓冲区对象。用于存储数据。
        StringBuffer sb = new StringBuffer();
        
        //2,添加数据。不断的添加数据后,要对缓冲区的最后的数据进行操作,必须转成字符串才可以。
        String str = sb.append(true).append("hehe").toString();
//        sb.append("haha");
        
//        sb.insert(2, "it");//插入
        
//        sb.delete(1, 4);//删除
        
//        sb.replace(1, 4, "cast");
//        sb.setLength(2);
        System.out.println(sb);
        
        
//        String s = "a"+5+'c';//原理就是以下这句
//        s = new StringBuffer().append("a").append(5).append('c').toString();
        
        
        
    }

}

  -------------------------------------

七,StringBuffer-练习

第一种方法是用字符串拼接的,第二种方法是用Stringbuffer拼接的.

package cn.itcast.api.stringbuffer;

public class StringBufferTest {

    /**
     * @param args
     */
    public static void main(String[] args) {
        
        /*
         * int[] arr = {34,12,89,68};
         * 将一个int[]中元素转成字符串  格式 [34,12,89,68]  //需求
         */
        int[] arr = {34,12,89,68};
        String str = toString_2(arr);
        System.out.println(str);
    }

    /**
     * 缓冲区的应用:无论多少数据,什么类型都不重要,只要最终变成字符串就可以StringBuffer这个容器。
     * @param arr
     * @return
     */
    public static String toString_2(int[] arr) {  //第二种方法
        //1,创建缓冲区。
        StringBuffer sb = new StringBuffer();
        
        sb.append("[");
        for (int i = 0; i < arr.length; i++) {
            if(i!=arr.length-1){
                sb.append(arr[i]+",");
            }else{
                sb.append(arr[i]+"]");
            }
        }
        
        
        return sb.toString();
    }

    public static String toString(int[] arr) {// 第一种方法
        
        //用字符串连接
        String str = "[";
        for (int i = 0; i < arr.length; i++) {
            if(i!=arr.length-1){
                str+=arr[i]+",";
            }else{
                str+=arr[i]+"]";
            }
        }
        return str;
    }

}

 ------------------------------------- 

八,Stringbuffer和Stringbuild的区别

package cn.itcast.api.stringbuffer;

public class StringBuilderDemo {

    /**
     * @param args
     */
    public static void main(String[] args) {

        /*
         * StringBuilder和StringBuffer的区别。
         * StringBuilder:非同步的。单线程访问效率高。
         * StringBuffer:同步的,多线程访问安全。
         * 
         */

    }
}
/*
synchronized append();

synchronized delete();

synchronized insert();

*/