Java必备基础七——字符串的基本常用方法、String、StringBuilder、StringBuffrer的区别(2021/9/21)更新

一些概念

  • 字符串被作为对象来处理
  • 内存分为栈内存、堆内存、常量池内存等若干个区域
  • 栈内存存放基本数据类型和对象的引用,堆内存存放对象本身(new修饰的对象),常量池存放字符串常量(直接用双引号定义的)和基本数据类型常量
  • 堆区:只存放类对象,线程共享;
  • 方法区:又叫静态存储区,存放class文件和静态数据,线程共享;
  • 栈区:存放方法局部变量,基本类型变量区、执行环境上下文、操作指令区,线程不共享;

一、字符串的创建

1.创建格式

首先明确字符串是java.lang包中的String类创建的,是对象,在类和对象那一节中学习到对象的创建方式是(详见Java基础学习二——类与对象):

类名 变量名 = new 类名([实参列表])

对于字符串的创建方式则有两种:

 格式1String str1 = "teacher";
 格式2String str2 = new String("teacher");

2.不同创建格式的区别

(1)格式1

  • 定义针对格式1中内存的存储形式的代码块时,如下:
String str1 = "teacher";
String str2 = "teacher";
  • 对应的内存的存储方式为:
    在这里插入图片描述
    可以看到第一种方式的"teacher"存储在常量池中,且每次创建一个新对象,只要常量的内容相同,常量内存的地址就是一致的;

(2)格式2

  • 定义针对格式2中内存的存储形式的代码块时,如下:
String str1 = new String("teacher");
String str2 = new String("teacher");
  • 对应的内存的存储方式为:
    在这里插入图片描述
    可以看到第二种方式的"teacher"存储在堆内存中,且每次创建一个新的对象,堆内存地址都是不一样的。

(3)两者区别

  • 举个例子强调两者的区别:
public class Example4_4 {
    public static void main(String[] args) {
        String s1 = new String("this is an example");//在堆中创建一个字符串
        String s2;
        s2 = new String("this is an example");//在堆中重新创建一个字符串       
        System.out.println("s1的内容是否等于s2的内容:" + s1.equals(s2));//equal判定对象内容是否相等
        System.out.println("s1和s2地址是否相等:" + (s1 == s2));//==判定两者堆中的地址和内容是否相等
        String s3, s4;
        s3 = "this is an example";
        s4 = "this is an example";
        System.out.println("s3的内容是否等于s4的内容:" + s3.equals(s4));//equal判定对象内容是否相等
        System.out.println("s3和s4地址是否相等:" + (s3 == s4));//==判定两者堆中的地址和内容是否相等
        String s5 = s1;//把s1中存放的地址赋给s5,s5也指向s1指向的字符串
        System.out.println("s1=s5:"+(s1==s5));//返回true
        System.out.println("s2=s5:"+(s2==s5));//返回false
        System.out.println("s3=s5:"+(s3==s5));//返回false
    }
}

输出内容为:

s1的内容是否等于s2的内容:true
s1和s2地址是否相等:false
s3的内容是否等于s4的内容:true
s3和s4地址是否相等:true
s1=s5:true
s2=s5:false
s3=s5:false

3.总结

  • 格式1:String str1 = “teacher”;程序运行时在常量池中找相同内容的字符串,将其常量池中的地址赋值给对象,常量池中内容相同的字符串的地址是相同的;
  • 格式2:String str2 = new String(“teacher”);程序会在堆内存中开辟一个新的空间存放型对象的地址且将其地址赋值给对象;堆内存中字符串内容相同的堆地址不一定相同;看有没有重新new新对象,new了新对象,堆地址会变化

二、字符串的常用方法

下面主要围绕这六种使用方法展开描述。
在这里插入图片描述

1.基本操作方法

(1)字符串连接:+或concat()

  • 使用+号
  • 使用concat(String str)的方法
String s1 = "I am";
String s2 = " a student";
String s3 = s1 + s2;
String s4 = s1.concat(s2);
int s5 = s1.concat(s2)
System.out.println(s3);
System.out.println(s4);
System.out.println("s3=s4:"+(s3==s4));//字1符串连接逻辑异常

输出结果:

I am a student
I am a student
s3=s4:false

(2)获取字符串长度方法:length()

  • String类中的length()方法,与数组长度length属性不同
  • 字符串中的汉字、英文字母、空格、符号都是一个字符
String str = "0";
str.length();

(3)去除空格:trim()

String str1 =" I     ";
String str2 = str1.trim();//str2的值为"I"

2.字符串比较

  • ==:用于比较两个字符串变量的地址,返回布尔值(true或false)
  • equals():比较两个字符串内容是否相同,返回布尔值
  • equalsIgnoreCase():忽略大小写比较内容是否相同,返回布尔值
  • compareTo():按字典顺序比较字符串,返回值为整数,若前者小于方法体里面的对象,返回小于0的值;若前者等于后者,返回0;若前者大于后者,返回大于0的值
String str1 = "bcd";
String str2 = "acd";
String str3 = "cd";
System.out.println(str1.compareTo(str2);//返回1
System.out.println(str1.compareTo(str3);//返回-1

3.字符串与其它类型转换

数据类型字符串👉其它类型其它👉字符串其它👉字符串
byteByte.parseByte(str)String.valueOf([byte] bt)Byte.toString([byte] bt)
intInterger.parseInt(str)String.valueOf([int] i)Int.toString([int] i)
longLong.parseLong(str)String.valueOf([long] l)long.toString([long] l)
floatFloat.parseFloat(str)String.valueOf([float] f)Float.toString([float] f)
doubleDouble.parseDouble(str)String.valueOf([double] d)Double.toString([double] d)
charStr.charAt(i)String.valueOf([char] c)Char.toString([char] c)
booleanBoolean.getBoolean(str)String.valueOf([boolean] b)Boolean.toString([boolean] b)

如下例子

 String s1 = null;       
 byte b=Byte.parseByte(s1);
 s1 = String.valueOf(b);
 Byte.toString(b);

4.查找字符串位置

  • indexOf(ch):在字符串中搜索指定的字符或字串,返回字符串第一次出现的位置,索引从0开始
  • indexOf(ch,fromIndex):返回指定索引位置后第一次出现该字符的索引号
  • lastIndexOf(ch):在字符串中搜索指定的字符或字串,返回字符串最后一次出现的位置
  • lastIndexOf(ch,fromIndex):在字符串中搜索指定的字符或字串,返回指定索引位置后最后一次出现该字符的索引号,找到就返回相应的下标,找不到就返回-1

5.查找字符串

(1)获取第i个字符:charAt()

  • charAt()方法
String str ="hello word";
char c1 = str.charAt(0);//c1的值为'h'
char c2 = str.chatAt(6);//c1的值为'w'

(2)获取指定位置的字符方法:getChars()

  • getChars():将字符从字符串中赋值到目标字符数组
    getChars(需要复制的字符串的开始索引,需要复制的字符串的结束索引,需要填充的数组,数组开始的索引号)
String s1 = "012345"
char[] chars = new char[9];
s1.getChars(2,4,chars,0);
System.out.println(chars);/截取字符串填充到数组中,输出为"23",只取到索引号4前面的字符串

(3)拆分字符串子串:split()

  • str.split("str1"):按指定字符(串)去分割str字符串,结果以字符串数组形式返回;
String str="1234@abc";
String[] a = str.split("@");
System.out.println("处理结果: "+a[0]+","+a[1]);   //输出的是: 处理结果: 1234,abc
  • str.split(正则表达式):用正则表达式中的符号拆分str字符串,结果以字符串数组形式返回
String str="5678|XYZ";
String[] b = str.split("\\|");  //注意这里用两个 \\,而不是一个\
System.out.println("处理结果: "+b[0]+","+b[1]);   //输出的是: 处理结果: 5678,XYZ
  • str.split(正则表达式/字符串,limit):用正则表达式(字符串)中的符号拆分str字符串,拆分成limit个字符串,结果以字符串数组形式返回
String str="Java string split test";
      String[] strarray=str.split(" ",2);//使用limit,最多分割成2个字符串
      for (int i = 0; i < strarray.length; i++)
          System.out.println(strarray[i]);
将输出:
Java
string split test

(4)截取字符串子串:substring()

  • str.substring(int begin):返回一个新的字符串,从begin位置开始到str字符串结束的字符串。字符串下标从0开始
  • str.substring(int begin,int end)
String str1 = "我每天学习";
String str2 = str1.substring(1);//str1="每天学习"
String str3 = str1.substring(0,3)//str2="我每天"

6.修改字符串

  • concat():合并字符串
  • toLowerCase():将全部字符转化为小写
  • toUpperCase():将全部字符转化为大写
  • replaceAll(str1,str2):匹配正则表达式,将所有的str1替换成str2
  • replaceFirst(str1,str2):匹配正则表达式,将第一个str1替换成str2
  • replace(str1,str2):匹配正则表达式,将所有str1替换成str2
String s1 = "I am";
String s2 = " a student";
String s8 = "01230123";
String s3 = s1.concat(s2);//s3="I am a student"
String s4=s1.toLowerCase();//s4 = "i am"
String s5=s1.toUpperCase();//s4 = "I AM"
String s6=s1.replaceAll("I","Y");//s5 = "Y am"
String s7=s8.replaceFirst("0","2");//s7="21230123"     

三、字符串的应用

1.猜生日和性别

/**
 * @author:
 * @date: 21-7-16
 * @description: 猜生日和性别
 * 根据用户提供的身份证号码,输出其生日和性别。身份证号码为18位,不考虑15位的身份证号码
 * 生日从身份证信息来获取(第7位到第14位)
 * 身份证倒数第2位为偶数时性别为女,其他为男
 */

class IdentityCard {
    private String identityNumber;//身份证号码

    public IdentityCard(String identityNumber) {

        this.identityNumber = identityNumber;
    }

    public String getIdentityNumber() {
        return identityNumber;
    }

    public void setIdentityNumber(String identityNumber) {
        this.identityNumber = identityNumber;
    }

    /**
     * @return 返回性别
     */
    public String getSex() {
        if (identityNumber.charAt(16) % 2 == 0) {
            return "女";
        } else {
            return "男";
        }
    }

    public String getBirth() {
        String year;
        String month;
        String day;
        year = identityNumber.substring(6, 10);
        month = identityNumber.substring(10, 12);
        day = identityNumber.substring(12, 14);
        return year + "年" + month + "月" + day + "日";
    }
}

public class TestIdentityCard {
    public static void main(String[] args) {
        String str = args[0];//args[0]获取用户所输入
        IdentityCard identityCard = new IdentityCard(str);
        System.out.println("身份证号码为:" + identityCard.getIdentityNumber());
        System.out.println(identityCard.getSex());
        System.out.println(identityCard.getBirth());
    }
}

测试类中的arg[0]引用了main()方法中参数数组的第一个元素。选择Run Configurations命令,打开Run Configurations面板,单击Arguments选项卡,在Program arguments文本框中输入要测试的身份证号码“123456199001011110”,再次点击运行程序,结果如下。详情可见一些常用快捷键与操作一文,里面有详细图片说明操作。

身份证号码为:12345619900101111019900101

2.忽略大小写比较字符串

/**
 * @author:
 * @date: 21-7-16
 * @description: 比较两个字符是否相等
 */
public class Example4_8 {
    public static  void main(String[] args){
        String str1 = args[0];
        String str2 = args[1];
        if(str1.equalsIgnoreCase(str2)){
            System.out.println("两个字符串相等");
        } else {
            System.out.println("两个字符串不相等");
        }
    }
}

四、StringBuffer类

1.创建StringBuffer对象

StringBuffer有若干重载的构造方法用于创建对象,常用三种,也可参考JDK帮助文档,此文档中包含了很多编程类知识。

  • public StringBuffer():该方法构造了一个没有字符的字符串缓冲区,缓冲区的初始容量式16个字符:
StringBuffer strBuf = new StringBuffer();
  • public StringBuffer(int length):该方法构造了一个没有字符的字符串缓冲区,缓冲的长度由参数length确定,如:
StringBuffer strBuf = new StringBuffet(29);//缓冲区的长度为29个字符
  • public StringBuffer(String str):该方法用给定的参数str构造一个字符串缓冲区,初始容量为字符串str的长度加16个字符,如:
StringBuffer strBuf = new StringBuffer("初始化");//缓冲区的长度为19个字符,存放了“初始化”

2.StringBuffer的常用方法

(1)length():返回缓冲区的字符串中字符的个数,如果没有字符,返回0
(2)capacity():返回缓冲区的当前容量,而不是字符个数
(3)append():拼接两个字符串

StringBuffer strBuf = new StringBuffer("abc");
String str = strBuf.append("def");//str = "abcdef"

(4)insert():在字符串的指定位置中插入新内容,有多个重载方法

  • StringBuffer insert(int index,char c);
  • StringBuffer insert(int index,int i);
  • StringBuffer insert(int index,float f);
  • StringBuffer insert(int index,double d);
  • StringBuffer insert(int index,long l);

(5)delete(int start,int end):删除strBuf缓冲区字符串中下标从start(包含)到end(不包含)间的字符,下标从0开始

StringBuffer strBuf = new StringBuffer("hello word");
strBuf.delete(int 0,int 5);
System.out.println(strBuf);//输出word

(6)setCharAt(int index,char ch):将strBuf缓冲区字符串中下标为index的字符替换成ch

StringBuffer strBuf = new StringBuffer("Welcome to");
strBuf.setCharAt(1,'E');
strBuf.setCharAt(6,'E');
System.out.println(strBuf);//输出WElcomeE to

五、StringBuilder类

1.创建StringBuilder对象

StringBuilder又称为可变字符序列,它是一个类似于 String 的字符串缓冲区,通过某些方法调用可以改变该序列的长度和内容。

StringBuilder strBui = new StringBuilder();

2.StringBuilder的常用方法

(1)构造方法

  • public StringBuilder():构造一个空的StringBuilder容器
  • public StringBuilder(String str):构造一个StringBuilder容器,并将字符串添加进去
/*
 java.lang.StringBulider类;字符串缓冲区,可以提高字符串的效率
 构造方法:
         -public StringBuilder();构造一个空的StringBuilder容器
         -public StringBuilder(String str);构造一个StringBuilder容器,并将字符串添加进去
 */
public class Demo{
    public static void main(String[] args) {
        StringBuilder bu1 = new StringBuilder();
        System.out.println("bu1"+bu1);// bu1

        StringBuilder bu2 = new StringBuilder("abc");
        System.out.println("bu2:"+bu2);// bu2:abc
    }
}

(2)成员方法

  • public StringBuilder append():返回当前对象本身(this)
  • reverse():缓冲区内容反转,从后往前
  • 通过toString方法,StringBuilder对象将会转换为不可变的String对象。
  • 通过toString方法,StringBuilder对象将会转换为不可变的String对象
/*
StringBuilder类的成员方法:
     public StringBuilder append(...);添加任意类型数据的字符串形式,并返回当前对象本身
     参数是任意的数据类型
     reverse方法
      字符串反转
 */
public class Demo{
    public static void main(String[] args) {
        //创建StringBuilder对象
        StringBuilder bu1 = new StringBuilder();
        //使用append方法往StringBuilder中添加数据
        StringBuilder bu2 = bu1.append("abc");
        System.out.println(bu1);  //abc
        System.out.println(bu2);  //abc
        System.out.println(bu1==bu2);  //true 两个对象是同一个对象

        //使用append方法无需接收返回值
        bu1.append("abc");
        bu1.append(1);
        bu1.append(true);
        bu1.append(1.3);
        bu1.append("中");
        System.out.println(bu1);//abcabc1true1.3中

        //链式编程:方法的返回值是一个对象,可以根据对象继续调用方法
        System.out.println("abc".toUpperCase().toLowerCase());
        bu2.append("abc").append(1).append(true).append(1.3).append("中");
        System.out.println(bu2); //abcabc1true1.3中abc1true1.3中

        //reverse方法
        //字符串反转
        bu2.reverse();
        System.out.println("bu2反转:"+bu2); //bu2反转:中3.1eurt1cba中3.1eurt1cbacba
        System.out.println( bu2.toString());
    }
}

六、String、StringBuilder、StringBuffrer的区别

  • String类是不可变类,任何对String的改变都会引发新的String对象的生成;

  • StringBuffer是可变类,任何对它所指代的字符串的改变都不会产生新的对象,线程安全的。

  • StringBuilder是可变类,线性不安全的,不支持并发操作,不适合多线程中使用,但其在单线程中的性能比StringBuffer高。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值