String、StringBuffer、StringBuilder类及其常用方法

目录

一.String类

1.String的特性

2.字符串对象的存储

3.字符串的特性

 4.使用String时需要注意的地方

5.String 中常用方法

6.常见算法题目

二.StringBuffer类

1.StringBuffer类的性质

2.StringBuffer类的常用方法

三.StringBuilder类


 

一.String类

1.String的特性

(1)String类:代表字符串。

(2)String是一个final类,代表不可变的字符序列。

(3)字符串是常量,用双引号引起来表示。它们的值在创建之后不能更改。

 

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final char value[];

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

2.字符串对象的存储

(1)String对象的字符内容是存储在一个字符数组value[]中的。

(2)字符串常量存储在字符串常量池中,目的是实现共享。字符串非常量对象存储在堆中。

例题:

public class Demo02 {
    public static void main(String[] args) {
        String s1="javaSE";
        String s2="javaSE";
        String s3=new String("javaSE");
        String s4=new String("javaSE");

        System.out.println(s1==s2);//true
        System.out.println(s1==s3);//false
        System.out.println(s1==s4);//false
        System.out.println(s3==s4);//false
    }
}

内存图分析:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5bCP5p2o5LiN5LyaSmF2YQ==,size_20,color_FFFFFF,t_70,g_se,x_16

3.字符串的特性

(1)常量与常量的拼接结果在常量池。且常量池中不会存在相同内容的常量。

(2)只要其中有一个是变量,结果就在堆中。

(3)如果拼接的结果调用intern()方法,返回值就在常量池中。

public class Demo03 {
    public static void main(String[] args) {
        String s1="hello";
        String s2="word";
        String s3="hello"+"word";
        String s4=s1+"world";
        String s5=s1+s2;
        String s6=(s1+s2).intern();

        System.out.println(s3==s4);//false
        System.out.println(s3==s5);//false
        System.out.println(s4==s5);//false
        System.out.println(s3==s6);//true
    }
}

内存图分析:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5bCP5p2o5LiN5LyaSmF2YQ==,size_20,color_FFFFFF,t_70,g_se,x_16

 4.使用String时需要注意的地方

(1)String  s1="a" ; 说明:在字符串常量池中创建了一个字面量为“a”的字符串。

(2)s1=s1+"b"; 说明:实际上原来的"a"字符串对象已经丢弃了,现在在堆空间中产生了一个字符串s1+"b"(也就是"ab")。如果多次执行这些改变字符串内容的操作,会导致大量副本字符串对象存留在内存中,降低效率。如果这样的操作放到循环中,会极大影响程序的性能。

(3)String  s2="ab"; 说明:直接在字符串常量池中创建一个·字面量为"ab"的字符串。

(4)String  s3="a"+"b"; 说明:s3指向字符串常量池中已经创建的"ab"的字符串。

(5)String  s4=s1.intern(); 说明:堆空间的s1对象在调用intern()之后,会将常量池中已将存在的"ab"字符串赋值给s4。

5.String 中常用方法

(1)int length(): 返回字符串的长度

(2)char charAt(int index): 返回某索引处的字符

(3)boolean isEmpty():判断是否是空字符串

(4)String toLowerCase():使用默认语言环境,将 String 中的所有字符转换为小写

(5)String toUpperCase():使用默认语言环境,将 String 中的所有字符转换为大写

(6)String trim():返回字符串的副本,忽略前导空白和尾部空白

(7)boolean equals(Object obj):比较字符串的内容是否相同

(8)int compareTo(String anotherString):比较两个字符串的大小

(9)String substring(int beginIndex):返回一个新的字符串,它是此字符串的从 beginIndex开始截取到最后的一个子字符串。

(10)String substring(int beginIndex, int endIndex) :返回一个新字符串,它是此字 符串从beginIndex开始截取到endIndex(不包含)的一个子字符串。

(11)String[] split(String regex):根据给定正则表达式的匹配拆分此字符串。

(12)int indexOf(String str):返回指定子字符串在此字符串中第一次出现处的索引

6.常见算法题目

1.模拟一个trim方法,去除字符串两端的空格。

public class Demo04 {
    public static void main(String[] args) {
        String str="  XiaoYang  ";
        String s=Trim(str);
        System.out.println("去除两端的空格后,字符串为:"+s);
    }
    public static String Trim(String str){
        if(str == ""){//判断字符串是否为空,如果为空,则返回str
            return str;
        }else {
            int startIndex=0;
            int endIndex=0;
            char[] arr=str.toCharArray();//将字符串转变成字符数组,方便对单个字符操作
            for(int i=0;i<arr.length;i++){//从前往后遍历,找到第一个不为空格的位置并记录下来
                if(arr[i]!=' '){
                    startIndex=i;
                    break;
                }
            }
            for(int i=arr.length-1;i>=0;i--){从后往前遍历,找到第一个不为空格的位置并记录下来
                if(arr[i]!=' '){
                    endIndex=i;
                    break;
                }
            }
          return str.substring(startIndex,endIndex+1);//左闭右开

        }
    }

}

2.将一个字符串进行反转。将字符串中指定部分进行反转。比如“abcdefg”反转为“abfedcg”

public class Demo05 {
    public static void main(String[] args) {
        String str="abcdefg";
        String s=Reverse(str,2,5);
        System.out.println("反转后的字符串为:"+s);
    }

    public static String Reverse(String str,int startIndex,int endIndex){
        if(str==null){//判断字符串是否为空
            return null;
        }else{
            char[] arr=str.toCharArray();//将字符串转化成字符数组
            for(int i=startIndex,j=endIndex;i<j;i++,j--){//对startIndex-endIndex进行反转
                char t=arr[i];
                arr[i]=arr[j];
                arr[j]=t;
            }
            return new String(arr);//返回已经反转后的字符串
        }
    }
}

3.获取一个字符串在另一个字符串中出现的次数。 比如:获取“ ab”在 “abkkcadkabkebfkabkskab” 中出现的次数。

public class Demo06 {
    public static void main(String[] args) {
        String str="abkkcadkabkebfkabkskab";
        String sonStr="ab";
        int count=Times(str,sonStr);
        System.out.println("子字符串在字符串中出现的次数是"+count);
    }
    public static int  Times(String str,String sonStr){
        if(str.length()<sonStr.length()){//判断子字符串要比字符串的长度短
            return 0;
        }else{
            int index,count=0;//定义两个变量,index用于记录找到子字符串的位置,count用于记录找到子字符串的个数
            while((index=str.indexOf(sonStr))!=-1){//判断字符串中是否还有子字符串
                count++;
                /*
                找到子字符串后,截取字符串从(index+子字符串的长度)到字符串的末尾
                重复此过程,直到字符串中不含有子字符串,返回此时的count值
                 */
                str=str.substring(index+sonStr.length());
            }
            return count;
        }
    }
}

4.获取两个字符串中最大相同子串。比如: str1 = "abcwerthelloyuiodef“;str2 = "cvhellobnm".

public class Demo07 {
    public static void main(String[] args) {
        String sStr = "cvhellobnm";
        String lStr = "abcwerthelloyuiodef";
        String s = BigSameStr(sStr, lStr);
        System.out.println(s);
    }

    public static String BigSameStr(String shortStr, String longStr) {
        if (shortStr.length() > longStr.length()) {
            return null;
        }
        else {
            String str=" ";
            /*
            利用双层for循环找到长度较短的字符串中所有的子串
            判断长字符串是否包含子串,若包含,则跟上一个比较长度
            将长度长的子串并且满足包含于长字符串的字符串保存
            循环结束最后保存的就是长度最长且包含于长字符串的字符串
             */
            for (int i = 0; i < shortStr.length() - 1; i++) {
                for (int j = shortStr.length() ; j > i; j--) {
                    String newStr;
                    newStr = shortStr.substring(i, j);
                    if (longStr.contains(newStr) &&newStr.length()>=str.length()) {
                        str=newStr;
                    }
                }
            }
            return str;
        }
    }
}

二.StringBuffer类

1.StringBuffer类的性质

(1)java.lang.StringBuffer代表可变的字符序列,JDK.0中声明,可以对字符串内容进行增删,此时不会产生新的对象。

(2)StringBuffer的很多方法与String相同。

(3)作为参数传递时,方法内部可以改变值。

(4)StringBuffer类不同于String,其对象必须使用构造器生成。有三个构造器:

        ①StringBuffer():初始容量为16的字符串缓冲区。

        ②StringBuffer(int size):构造指定容量的字符串缓冲区。

        ③StringBuffer(String str):将内容初始化为指定字符串内容。

abstract class AbstractStringBuilder implements Appendable, CharSequence {
    /**
     * The value is used for character storage.
     */
    char[] value;//value没有final声明,value可以不断扩容

    /**
     * The count is the number of characters used.
     */
    int count;//count记录有效字符的个数

2.StringBuffer类的常用方法

(1)StringBuffer append(xxx):用于字符串拼接。

(2)StringBuffer delete(int start,int end):删除指定位置的内容。

(3)StringBuffer replace(int start,int end,String str):把[start,end)位置替换为str。(注意左闭右开)

(4)StringBuffer reverse():把当前字符序列逆转

(5)StringBuffer insert(int offset,xxx):在指定位置offset插入xxx。 

(6)StringBuffer substring(inr start,int end):在[start,end)截取x新的字符串。(注意左闭右开)

(7)StringBuffer length():返回该字符串的长度。

(8)StringBuffer charAt(int n):返回字符串上n的位置的字符

(9)StringBuffer setCharAt(int n,char ch):将自负床中位置为n的字符变为ch。

注意:①:当使用append和insert方法时,如果原来的value数组长度不够,可扩容。

           ②:如上这些方法支持方法链操作

           ③:方法链的原理是:

    @Override
    public synchronized StringBuffer append(CharSequence s) {
        toStringCache = null;
        super.append(s);
        return this;
    }

三.StringBuilder类

1.StringBuilder与StringBuffer非常相似,均可代表可变的字符序列,而且提供相关的方法也一样。

2.相关面试题:

(1)对比String、StringBuffer、StringBuilder

        String:不可变字符序列

        StringBuffer:可变字符序列、效率低、线程安全。

        StringBuilder:可变字符序列、效率高、线程不安全。

    注意:作为参数传递的话,方法内部String不会改变其值,StringBuffer与StringBuilder会改变其值。

(2)程序输出:

public class Demo10 {
    public static void main(String[] args) {
        String str = null;
        StringBuffer sb = new StringBuffer();
        sb.append(str);
        System.out.println(sb.length());//输出:4
        System.out.println(sb);//输出:null
        
        StringBuffer sb1 = new StringBuffer(str);
        System.out.println(sb1);//输出:      
    }
}

分析:前边两个输出没有问题,sb拼接str的字符串,此时sb=null,长度为4。第三个输出语句我们便要考虑StringBuffer有参构造器的底层了,,此时编译是没有问题的,但是由于传进去的str为null值,str.length()就会导致出现空指针异常NullPointerException。

    public StringBuffer(String str) {
        super(str.length() + 16);
        append(str);
    }

所以正确的在StringBuffer添加null值时 采用下面这个方法:

​
        String str = null;
        StringBuffer sb = new StringBuffer();
        sb.append(str);

​

 

 

 

 

 

 

 

 

 

 

  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小杨不会Java

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值