Java字符串(String)相关的类:String、StringBuffer、StringBuilder

Java字符串(String)相关的类

String类及常用方法

String类

String的特性
  • String类:代表字符串。Java程序中的所有字符串字面值(如"abc")都作为此类的实例实现
  • String类是一个final类,代表不可变的字符序列
  • 字符串是常量,用双引号引起来表示,它们的值在创建后不可更改
  • String对象的字符内容是储存在一个字符组value[]中的
public final class String implements java.io.Serializable, java.lang.Comparable<java.lang.String>, java.lang.CharSequence {
    
}
  • 特性举例说明
package www.bh.c.string;

public class test01 {
/*1.String:字符串,用一对""引起来表示
2.String声明为final,不可以被其它类继承
3.String实现了Serializable接口,表示字符串是支持序列化的
4.String实现了Comparable接口,表示String可以比较大小
5.String内部定义了final char[] value用于储存字符串数据
6.通过字面量的方式(区别于new)给一个字符串赋值,此时的字符串值声明在字符串常量池中
7.字符串常量池中是不会在不同位置储存相同内容的字符串的
*/
   public static void main(String[] args) {
        String a="abc";   //字面量的定义方式
        String b="abc";

        System.out.println(a == b);//比较a和b的地址值  true
        System.out.println(a);//abc
        System.out.println(b);//abc
    }
}
package www.bh.c.string;

public class test01 {
      /* String代表不可变的字符序列,简称不可变性
       具体体现:1.当对字符串重新赋值时,需要重新指定内存区域赋值,不能使用原有的value值赋值*/
        public static void main(String[] args) {
        String a="abc";   //字面量的定义方式
        String b="abc";
        a="hello";//重写赋值
        System.out.println(a == b);//比较a和b的地址值  flase
        System.out.println(a);hello
        System.out.println(b);//不可变性,b仍为abc
    }
}
package www.bh.c.string;

public class test02 {
    public static void main(String[] args) {
        //2.当对现有的字符串进行连接操作时,需要重新指定内存区域赋值,不能使用原有的value值赋值
         String s1="abc"; 
        String s2="abc";
        s1+="def";
        System.out.println(s1 == s2);//比较s1和s2的地址值  false
        System.out.println(s1);//abcdef
        System.out.println(s2);//不可变性,abc
    }
}
package www.bh.c.string;

public class test02 {
    public static void main(String[] args) {
        //3.当调用String的replace()方法修改指定的字符或字符串时,也需要重新指定内存区域赋值
        String s1="abc";
        String s2="abc";
        String s3 = s1.replace("a", "m");

        System.out.println(s3 == s2);//比较s3和s2的地址值
        System.out.println(s1);//abc
        System.out.println(s2);//不可变性,abc
        System.out.println(s3);//mbc
    }
}
String对象的创建
  • String类的实例化方式
    • 通过字面量定义的方式
    • 通过new+构造器的方式
package www.bh.c.string;

public class Test03 {
    public static void main(String[] args) {
        //通过字面量定义的s1和s2的数据JavaEE存在在方法区的字符串常量池中
        String s1="JavaSE";
        String s2="JavaSE";
        //通过new+构造器定义的s1和s2:s1和s2存的是地址值,是数据在堆空间中开辟空间以后对应的地址值
        String s3=new String("JavaEE");
        String s4=new String("JavaEE");
        System.out.println(s1 == s2);//true(常量池)
        System.out.println(s1 == s3);//false(常量池和地址值)
        System.out.println(s1 == s4);//false(常量池和地址值)
        System.out.println(s3 == s4);//false(地址值)

    }
}
package www.bh.c.string;

public class Test04 {
    String name;
    int age;

    public Test04(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public Test04() {
    }

    public static void main(String[] args) {
        //j1和j2存的是地址值,是数据在堆空间中开辟空间以后对应的地址值
        //对应的值在常量池中
        Test04 j1 = new Test04("Java", 15);
        Test04 j2 = new Test04("Java", 15);
        System.out.println(j1.name.equals(j2.name));//equals比较的是实际的值是否相等 true
        System.out.println(j1.name== j2.name);//常量池中  true
        System.out.println(j1.age == j2.age);//常量池中  true
        System.out.println(j1 == j2);//地址值  flase
    }
}
//思考:String s=new String("abc")创建对象,在内存中创建了几个对象?
    
//两个:一个是堆空间中new结构,另一个是char[]对应的常量池中的数据:"abc"
  • 常量与常量的拼接结果在常量池中,且常量池中不会存在相同内容的常量
  • 只要拼接的其中一个是变量,结果就存在在堆中
  • 如果拼接的结果是调用intern()方法,返回值就在常量池中
ackage www.bh.c.string;

public class Test05 {
    public static void main(String[] args) {
        String s1="abc";
        String s2="def";

        String s3="abcdef";
        String s4="abc"+"def";//拼接结果在常量池中
        String s5=s1+"def";//拼接的其中一个是变量,结果就存在在堆中
        String s6="abc"+s2;//堆中
        String s7=s1+s2;//堆中
        System.out.println(s3 == s4);//true
        System.out.println(s3 == s5);//false
        System.out.println(s3 == s6);//false
        System.out.println(s3 == s7);//false
        System.out.println(s5 == s6);//false
        System.out.println(s5 == s7);//false
        
        String s8=s5.intern();//调用intern()方法,返回值s8存在在常量池中
        System.out.println(s3 == s8);//true
        
        System.out.println("=============");
        final String s9="def";//final定义,s9为常量
        String s10="abc"+s9;//实质上常量与常量的拼接
        System.out.println(s3 == s10);//true
    }
}
面试常见题
package www.bh.c.string;

public class Test06 {
    String s1=new String("test");
    char[] c1={'t','e','s','t'};
    public void change(String s1,char[] c1){
        s1="best";
        c1[0]='b';
    }

    public static void main(String[] args) {
        Test06 t1 = new Test06();
        System.out.println(t1.s1);
        System.out.println(t1.c1);
        System.out.println("============");
        t1.change(t1.s1,t1.c1);
        System.out.println(t1.s1);
        System.out.println(t1.c1);
    }
}
/*
test
test
============
test  //字符串的不可变性
best
*/
String类常用方法
  • int length():返回字符串的长度
package www.bh.c.string;

public class Test08 {
    public static void main(String[] args) {
        String s1="helloworld";
        System.out.println(s1.length());//10
    }
}
  • char charAt(int index):返回指定索引处的字符
package www.bh.c.string;

public class Test08 {
    public static void main(String[] args) {
        String s1="helloworld";
        System.out.println(s1.charAt(5));//w
    }
}
  • boolean is Empty():判断是否是空字符串
package www.bh.c.string;

public class Test08 {
    public static void main(String[] args) {
        String s1="helloworld";
        System.out.println(s1.isEmpty());//false
    }
}
  • String toLowerCase():使用默认语言环境,将String中的所有字符转为小写

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

package www.bh.c.string;

public class Test08 {
    public static void main(String[] args) {
        String s1="helloworld";
        System.out.println(s1.toLowerCase());//helloworld
        System.out.println(s1.toUpperCase());//HELLOWORLD
    }
}
  • String trim():返回字符串的副本,忽略前导空白和后导空白
package www.bh.c.string;

public class Test08 {
    public static void main(String[] args) {
        String s1="  he  ll  ow  or  ld  ";
        System.out.println(s1.trim());//"he  ll  ow  or  ld"
    }
}
  • boolean equals(Object obj):比较字符串的内容是否相同
  • boolean equalsIgnoreCase(String anotherString):忽略大小写,比较字符串的内容是否相同
  • String concat(String str):将指定字符串连接到此字符串的结尾。等价于"+"
  • int compareTo(String anotherString):比较两个字符串的大小
package www.bh.c.string;

public class Test08 {
    public static void main(String[] args) {
        String s1="helloworld";
        String s2="HelloWorld";
        System.out.println(s1.equals(s2));//true
        System.out.println(s1.equalsIgnoreCase(s2));//false
        System.out.println(s1.concat("你好"));//helloworld你好
        System.out.println(s1.compareTo(s2));//32,涉及到字符串排序,正数为后面的大,负数为后面的小,
    }
}
  • String substring(int beginIndex):从beginIndex开始截取一个新的子字符串
  • String substring(int beginIndex,int endIndex):从beginIndex开始,endIndex(不包含)结束截取一个新的子字符串
package www.bh.c.string;

public class Test08 {
    public static void main(String[] args) {
        String s1="helloworld";
        System.out.println(s1.substring(5));//world
        System.out.println(s1.substring(0, 5));//hello
    }
}
  • boolean endsWith(Stirng suffix):测试此字符串是否以指定的后缀结束

  • boolean startsWith(Stirng prefix):测试此字符串是否以指定的前缀开始

  • boolean startsWith(Stirng prefix,Stirng toffset):测试此字符串从指定索引开始的子字符串是否以指定前缀开始

package www.bh.c.string;

public class Test08 {
    public static void main(String[] args) {
        String s1="helloworld";
        System.out.println(s1.endsWith("d"));//true
        System.out.println(s1.endsWith("ld"));//true
        System.out.println(s1.endsWith("world"));//true
        System.out.println(s1.startsWith("he"));//true
        System.out.println(s1.startsWith("l",2));//true
        System.out.println(s1.startsWith("l",3));//true
    }
}
  • boolean contains(CharSequence s):当且仅当此字符串包含指定的char值序列时,返回true
  • int IndexOf(String str):返回指定子字符串在此字符串中第一次出现处的索引
  • int IndexOf(String str,int formIndex):返回指定子字符串在此字符串中第一次出现的索引,从指定的索引开始
  • int lastIndexOf(String str):返回指定子字符串在此字符串中最右边出现处的索引
  • int lastIndexOf(String str,int formIndex):返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索
  • 注:IndexOf和lastIndexOf方法如果未找到都是返回-1
package www.bh.c.string;

public class Test08 {
    public static void main(String[] args) {
        String s1="helloworld";
       String s2="low";
        System.out.println(s1.contains(s2));//true
        System.out.println(s1.indexOf("ll"));//2
        System.out.println(s1.indexOf("o",5));//6
        System.out.println(s1.lastIndexOf("or"));//6
        System.out.println(s1.lastIndexOf("or",9));//6
    }
}
  • String replace(char oldChar,char newChar):返回一个新字符串,newChar替代此字符串中出现的所有的oldChar
  • String replace(CharSequence target,CharSequence replacement):使用指定的字面值替换序列替换此字符串所有匹配字面值目标序列的子字符串
package www.bh.c.string;

public class Test09 {
    public static void main(String[] args) {
        String s1="快乐学习学习快乐";
        String s2=s1.replace('乐','快');
        String s3=s1.replace("快乐","十分快乐");
        System.out.println(s2);//快快学习学习快快
        System.out.println(s3);//十分快乐学习学习十分快乐
    }
}
  • String replaceAll(String regex,String replacement):使用指定的 replacement替换替换此字符串所有匹配给定的正则表达式的子字符串
package www.bh.c.string;

public class Test09 {
    public static void main(String[] args) {
        String s1="12ab34cd45ef";
        String s2=s1.replaceAll("\\d+",".");
        System.out.println(s2);//.ab.cd.ef
    }
}
  • boolean matches(String regex):告知此字符串是否匹配给定的正则表达式
package www.bh.c.string;

public class Test09 {
    public static void main(String[] args) {
        String s1="123456";
        //判断s1字符串是否全部由有效的数字组成
        boolean s2=s1.matches("\\d+");
        System.out.println(s2);
        String tel="0992-8888888";
         //判断tel是否是一个有效的固定电话
        boolean s3=tel.matches("0992-\\d{7,8}");
        System.out.println(s3);
    }
}
  • String[] split(String regex):根据给定正则表达式的匹配拆分此字符串
public class Test09 {
    public static void main(String[] args) {
        String s1="学习,Java,是,最快乐,的事";
        String[] s2=s1.split(",");
        for (int i=0;i<s2.length;i++){
            System.out.println(s2[i]);
        }
    }
}
/*
学习
Java
是
最快乐
的事
*/
  • String[] split(String regex,int limit):根据匹配给定的正则表达式来拆分此字符串,最多不超过limit个,如果超过了,剩下的全部都放到最后一个元素中
package www.bh.c.string;

public class Test09 {
    public static void main(String[] args) {
        String s1="学习,Java,是,最快乐,的事";
        String[] s2=s1.split(",",3);
        for (int i=0;i<s2.length;i++){
            System.out.println(s2[i]);
        }
    }
}
/*
学习
Java
是,最快乐,的事
*/
String类的类型转换
  • 字符串与基本数据类型转换

    • 字符串—>基本数据类型

      • Integer包装类的public static int parseInt(String s):可以将由“数字”字符组成的字符串转换为整型

      • 类似的,使用java.lang包中的Byte、Short、Long、Float、Double类相应的类方法可以将由“数字”字符组成的字符串,转化为相应的基本数据类型

    • 基本数据类型—>字符串

      • 调用String类的public String valueOf(int n)可将int型转换为字符串

      • 相应的valueOf(byte b)、valueOf(long l)、valueOf(float f)、valueOf(double d)、valueOf(boolean b)可由参数的相应类型到字符串的转换

package www.bh.c.stringswitch;

public class Test01 {
    public static void main(String[] args) {
        String str="1234";
        int num =Integer.parseInt(str);//转换为整型
        System.out.println(num);//1234

        String str1=String.valueOf(num);//由int型转换为字符串
        System.out.println(str1);//"1234"
        System.out.println(str == str1);//false
    }
}
  • 字符串与字符数组转换
    • 字符数组—>字符串
      • String类的构造器:String(char[])和String(char[],int offset,int length)分别用字符数组中的全部字符和部分字符创建字符串对象
    • 字符串—>字符数组
      • public char[] toCharArrey():将字符串中的全部字符存放在一个字符数组中的方法
      • public void getChars(int srcBegin,int srcEnd,char[] dst,int dstBegin) :提供了将指定索引范围内的字符串存放到数组中的方法
package www.bh.c.stringswitch;

public class Test02 {
    public static void main(String[] args) {
        String s="abcd";
        //String--->char[]:调用String类的toCharArray()方法
        char[] c=s.toCharArray();
        for (int i = 0; i < c.length; i++) {
            System.out.println(c[i]);//{'a','b','c','d'}
        }
        //char[]--->String:调用String的构造器
        String s1 = new String(c);
        System.out.println(s1);//abcd
    }
}
  • 字符串与字节数组转换
    • 字节数组—>字符串
      • String(byte[]):通过使用平台的默认字符集解码指定的byte数组,构造一个新的String
      • String(byte[],int offset,int length):用指定的字节数组的一部分,即从数组起始位置offset开始取length个字节构造一个字符串对象
    • 字符串—>字节数组
      • public byte[] getBytes():使用平台的默认字符集此String编码为byte序列,并将结果储存到一个新的byte数组中
      • public byte[] getBytes(String charseName):使用指定的字符集此String编码为byte序列,并将结果储存到一个新的byte数组中
package www.bh.c.stringswitch;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;

public class Test03 {
    public static void main(String[] args) throws UnsupportedEncodingException {
        String s="abc123学习";
        // String--->byte[]:调用String类的getBytes()方法
        //转换为二进制数据,也就是编码的过程
        byte[] b=s.getBytes();
        System.out.println(Arrays.toString(b));
        //输出为:[97, 98, 99, 49, 50, 51, -27, -83, -90, -28, -71, -96],UTF-8(默认的字符集)字符集中一个汉字由三个数字表示
        System.out.println("=============");
        //使用gbk字符集进行编码
        byte[] b1=s.getBytes("gbk");
        //输出为:[97, 98, 99, 49, 50, 51, -47, -89, -49, -80],gbk字符集中一个汉字由两个数字表示
        System.out.println(Arrays.toString(b1));
        
        System.out.println("=============");
        //byte[]--->String:调用String的构造器,使用默认的字符集,进行解码
        String s1=new String(b);
        System.out.println(s1);//abc123学习
        System.out.println("=============");
         //出现乱码,使用的编码集和解码集不一致:编码为gbk,解码为UTF-8
        String s2=new String(b1);
        System.out.println(s2);//abc123ѧϰ
        System.out.println("=============");
         //没有出现乱码,使用的编码集和解码集一致,都为:gbk
        String gbk = new String(b1, "gbk");
        System.out.println(gbk);
    }
}

StringBuffer类和StringBulider类

  • java.lang.StringBuffer代表可变的字符序列,可以对字符串内容进行增删,此时不会产生新的对象

  • 很多方法和String中的方法相同

  • 作为参数传递时,方法内部可以改变值

  • String、StringBuffer、StringBuilder三者的区别

    • String:不可变的字符序列:底层使用char[]存储
    • StringBuffer:可变的字符序列:线程安全,效率比StringBuilder低:底层使用char[]存储
    • StringBuilder:可变的字符序列,JDK5.0新增,线程不安全,效率高,底层使用char[]存储
package www.bh.c.stringbuffer;

public class stringb {
    public static void main(String[] args) {
        StringBuffer sb1 = new StringBuffer("abc");
        sb1.setCharAt(0,'m');//可变的字符序列,不需要返回值,直接替换了原来的值
        System.out.println(sb1);//mbc
    }
}
  • 源码分析
package www.bh.c.stringbuffer;

public class stringb {
    public static void main(String[] args) {
        String s = new String();//char[] value=new char[0]
        System.out.println(s.length());//0
        String s1 = new String("abc");//char[] value=new char[3]{'a','b','c'}

        StringBuffer sb = new StringBuffer();//char[] value=new char[16]  //底层创建了一个长度为16的数组
        System.out.println(sb.length());//0,value为16,count为0
        sb.append('d');//value[0]='d'
        sb.append("def");

        StringBuffer sb1 = new StringBuffer("abc");//char[]value=new char[ab1.length()+16]
        System.out.println(sb1.length());//3
    }
}

注:

  • 如果要添加的数据底层数据放不下了,那就需要扩容底层的数组,默认情况下,扩容为原来容量(最初容量为16)的2倍+2,同时将原有数组中的元素复制到新的数组中;如果新添加的很长,那就以要添加的数组长度为新的数组长度
  • 开发中建议使用:StringBuffer(int capacity)或StringBuilder(int capacity)

StringBuffer类的常用方法

  • StringBuffer append():提供了许多类型的append()方法,用于进行字符串拼接
package www.bh.c.stringbuffer;

public class Test01 {
    public static void main(String[] args) {
        StringBuffer ab = new StringBuffer("abc");
        ab.append(1);
        ab.append("def");
        System.out.println(ab);//abc1def
    }
}
  • StringBuffer delete(int start,int end):删除指定位置的内容
package www.bh.c.stringbuffer;

public class Test01 {
    public static void main(String[] args) {
        StringBuffer ab = new StringBuffer("abcdef");
        ab.delete(0,3);
        System.out.println(ab);//def
    }
}
  • StringBuffer replace(int start,int end,String str):将[start,end)位置替换为str
package www.bh.c.stringbuffer;

public class Test01 {
    public static void main(String[] args) {
        StringBuffer ab = new StringBuffer("你好中国");
        ab.replace(0,2,"hello");
        System.out.println(ab);//hello中国
    }
}
  • StringBuffer Insert(int offset,str):在指定位置插入str
package www.bh.c.stringbuffer;

public class Test01 {
    public static void main(String[] args) {
        StringBuffer ab = new StringBuffer("你好中国");
        ab.insert(2,"呀");
        System.out.println(ab);//你好呀中国
    }
}
  • StringBuffer reverse():把当前字符序列逆转
package www.bh.c.stringbuffer;

public class Test01 {
    public static void main(String[] args) {
        StringBuffer ab = new StringBuffer("你好");
        ab.reverse();
        System.out.println(ab);//好你
    }
}
  • public int indexOf(String str):返回指定子字符串在此字符串中第一次出现处的索引
package www.bh.c.stringbuffer;

public class Test01 {
    public static void main(String[] args) {
        StringBuffer ab = new StringBuffer("你好中国");
        int a = ab.indexOf("好");
        System.out.println(ab);//你好中国
        System.out.println(a);//1
    }
}
  • public String substring(int start,int end) :返回一个由start开始,end结束的左闭右开的子字符串
package www.bh.c.stringbuffer;

public class Test01 {
    public static void main(String[] args) {
        StringBuffer ab = new StringBuffer("abcdefg");
        String s = ab.substring(2, 5);
        System.out.println(ab);//abcdefg
        System.out.println(s);//cde
    }
}
  • public int length():长度
package www.bh.c.stringbuffer;

public class Test01 {
    public static void main(String[] args) {
        StringBuffer ab = new StringBuffer("abcdefg");
        System.out.println(ab.length());//7
    }
}
  • public char charAt(int n):返回指定索引的字符内容
package www.bh.c.stringbuffer;

public class Test01 {
    public static void main(String[] args) {
        StringBuffer ab = new StringBuffer("abcdefg");
        char c = ab.charAt(2);
        System.out.println(ab);//abcdefg
        System.out.println(5);//f
    }
}
  • public viod setCharAt(int n,char ch):修改将指定索引位置的字符内容
package www.bh.c.stringbuffer;

public class Test01 {
    public static void main(String[] args) {
        StringBuffer ab = new StringBuffer("abcdefg");
        ab.setCharAt(2,'d');
        System.out.println(ab);//abddefg
    }
}

注:1.StringBuffer、StringBuilder中的常用方法

  • 增:append()
  • 删:delete(int start,int end)
  • 改:setCharAt(int n,char ch) / replace(int start,int end, String str)
  • 查:charAt(int n)
  • 插:insert(int offset, xxx)
  • 长度:length()

2.String、StringBuffer、StringBuilder三者的效率对比

StringBuild>StringBuffer>String

3.String与StringBuffer、StringBuilder之间的转换

  • String—>StringBuffer、StringBuilder:调用StringBuffer、StringBuilder构造器
  • StringBuffer、StringBuilder—>String:调用String构造器:StringBuffer、StringBuilder的toString()方法

4.JVM中字符串常量池存放位置说明:

  • jdk1.6:字符串常量池存储在方法区(永久区)
  • jdk1.7:字符串常量池存储在堆空间
  • jdk1.8:字符串常量池存储在方法区(元空间)

你可能感兴趣的:(Java基础)