String引用类型的相关方法介绍和使用--------详细理解

引用类型String

  • Java提供了String、StringBuffer、StringBuilder类来创建和操作字符串。Java中字符串被当作是对象来处理,是引用类型数据

  • String类的内部:

在这里插入图片描述

  • String是一个被final修饰的类

  • String对象的字符串内容存储在被private和final修饰后的字符数组中、即value[]。

  • private意味着外面无法直接获取字符数组,而且String没有提供value的get和set方法。

  • final意味着字符数组的引用不可改变,即不可通过让value指向新的数组对象来实现修改

  • String 对象;而且String也没有提供方法来修改value数组某个元素值,因此字符串的字符数组内容也不可改变

  • 所以,字符串的拼接、字符串的截取、字符串的替换等操作每次都需要创建一个新的char数组表示修改后的结果

  • 字符串是不可被更改的对象,如果更改字符串的值,意味着创建一个新的字符串。

字符串内存分析

字面量
  • 字符串的每个字面量都是一个String对象,例:String str1=“diajw”
新建对象
  • 使用new创建字符串对象。例:String str1=new String(“diajw”);
字符串存储分析
  • 字面量保存在常量池中

  • 在编译代码时,编译程序会将所有字面量都保存在方法区中的常量池里。因此,相同字面量的所有对象,实际上就是存储于常量池中的同一个对象。例:

String str1="fmYweifi";
String str2="fmYweifi";
System.out.println(str1==str2);
//true s1和s2指向了常量池中的同一个对象,所以他们引用的是同一个地址,即s1和s2都指向了"fmYweifi"

String str3=new String("fmYweifi");
System.out.println(str1==str3);
//false 一个是指向的是常量池中的地址str1,另一个是指向堆中的地址str3,他们的引用地址不同,所以返回值是false
  • 存储分析图:

在这里插入图片描述

  • 总结:字符串常量存储在字符串常量池。常量池中的相同的字符串可共享

字符串常量存储在堆中

字符串的拼接:
//字符串的拼接
String str4="Pro";
String str5="cessOn";
String str6="Pro"+"cessOn";
System.out.println(str6);
String str7=str4+"cessOn";
System.out.println(str7);
String str8=str4+str5;
System.out.println(str8);
String str9=(str4+str5).intern();
System.out.println(str9);
  • 字符串在内存中的分析:

在这里插入图片描述

  • 总结:常量与常量的拼接结果在常量池

  • 拼接的两者中只要其中一个是变量,结果就在堆中

  • 拼接的结果调用intern()方法,就在常量池中

  • intern函数用来返回常量池中的某个字符串。如果常量池中已经存在该字符串,则直接返回常量池中该对象的引用,否则,在常量池中加入该对象,然后返回引用

比较字符串对象
String str1="fmYweifi";
String str2="fmYweifi";
System.out.println(str1==str2);
//true s1和s2指向了常量池中的同一个对象,所以他们引用的是同一个地址,即s1和s2都指向了"fmYweifi"

String str3=new String("fmYweifi");
System.out.println(str1==str3);
//false 一个是指向的是常量池中的地址str1,另一个是指向堆中的地址str3,他们的引用地址不同,所以返回值是false

常用方法

创建字符串
  • 第一种方法:通过byte字节数组的方式来创建字符串,再通过String对象来接收该byte的字节数组,这样字节码会转换为字节码(例:97=a,98=b),然后通过String类方法String(arr,offset:起始下标,length:取的长度)取出该字符串:如下代码
byte[] buf={97,98,99};
String str=new String(buf);
str=new String(buf,0,3);
System.out.println(str);
  • 第二种方法:使用字符数组构建字符串,通过char字符数组把它传给字符串对象,然后通过方法String(arr,offset:起始下标,取的字符个数);:如下代码

    char[] arr={'这','里','有','一','个','问','题'};
    str=new String(arr);
    str=new String(arr,3,2);
    System.out.println(str);
    
  • 第三种方法:使用int类型的数组创建字符串,把int数组传给字符串对象,然后通过方法String(arr,offset:数组起始下标,count:取的个数):如下代码:

int[] arr1={95,96,97,98,99};
String str1;
str1=new String(arr1,2,3);
System.out.println(str1);
  • 第四中方法:利用字符串创建字符串
String string=new String("abcdeg");
System.out.println("该字符串的输出为:"+string);

length

  • 获取字符串的长度

例:

String s="naffnjas";
System.out.println(s.length());

字符串转换为字节数组或者字符数组

  • 第一种方法:把字符串转换为字符数组,用.toCharArray()方法把字符串转换为字符数组,然后用Arrays.toString(数组变量名)输出
String str="Happiness";
char[] chars=str.toCharArray();
System.out.println("字符数组:"+ Arrays.toString(chars));
  • 第二种方法:把字符串转换为字节数组,用.getBytes()方法把字符串转换为字节数组,然后用Arrays.toString(数组变量名)输出

    String str1="Happiness";
    byte[] b=str1.getBytes();
    System.out.println("字节数组:"+Arrays.toString(b));
    

大小写转换

  • 用字符串对象调用方法.toUpperCase()时转换为大写

    String str2="Happiness";
    System.out.println("转换为大写:"+str2.toUpperCase());
    
  • 用字符串对象调用方法.toLowerCase()时转换为小写

String str2="Happiness";
System.out.println("转换为小写:"+str2.toLowerCase());

+

  • 实现字符串的连接。

  • 字符串和任意类型之间使用“+”,所有基本类型都转换为字符串,所有引用类型都会调用toString,最后再执行字符串连接。

    例:代码:

    int age=15;
    String s="He is "+age+" years old";
    String s1="He is ".concat(String.valueOf(age)).concat(" years old");
    String s3="He is ".concat(""+age).concat(" years old");
     System.out.println(s);
     System.out.println(s1);
     System.out.println(s3);
    

    由上述可知,将其它类型转换为字符串有两种方法:

  • 第一种:String.valueOf(变量名)

  • 第二种:“”+变量名

去掉字符两端的空格

trim

例:

String s="     abc       ";
System.out.println(s.trim());
String s2=s.trim();
System.out.println(s2.length());

判断相关方法

  • 该类方法返回值均为boolean类型
方法声明方法作用
public boolean equals(Object obj)比较字符串内容是否相同,区分大小写
public boolean equalsIgnoreCase(String str)比较字符串内容是否相同,忽略大小写
public boolean contains(String str)判断字符串是否包含另一个字符串
public boolean startsWith(String str)判断字符串是否以指定字符串开头
public boolean endsWith(String str)判断字符传是否以制定字符结尾
public boolean isEmpty()判断字符串是否为空

例:

String str="Demo.java";
System.out.println("判断字符串是否为空内容:"+str.isEmpty());
System.out.println("是否以指定的字符串开始:"+str.startsWith("De"));
System.out.println("是否以指定的字符串结束:"+str.endsWith("ja"));

System.out.println("判断字符串是否包含指定的内容:"+str.contains("Demo"));
System.out.println("判断两个字符串的内容是否一致:"+"DEMO.JAVA".equals(str));
System.out.println("判断两个字符串的内容是否一致(忽略大小写):"+"DEMO.JAVA".equalsIgnoreCase(str));

定位

  • 字符串中的索引值是从0开始的
方法声明方法作用
public char charAt(int index)获取指定索引值的字符
public int indexOf(int ch)返回此字符在字符串中第一次出现的索引值,如果都不匹配则返回-1
public int indexOf(String str)返回指定字符串在字符串中第一次出现的索引值,如果都不匹配则返回-1
public int lastIndexOf(int str)返回制定字符在字符串中最后一次出现的索引值,如果都不匹配则返回-1
public int lastIndexOf(String str)返回制定字符串在字符串中最后一次出现的索引值,如果都不匹配则返回-1

例:

String str="abc中国ab中国";
System.out.println("字符串的字符个数:"+str.length());
System.out.println("根据索引值获取对应的字符:"+str.charAt(3));
System.out.println("查找子串中第一次出现的索引值:"+str.indexOf("中国"));
System.out.println("查找子串最后一次出现的索引值:"+str.lastIndexOf("中国"));

替换

方法声明方法作用
public String replace(char old,char new)替换指定的字符

例:

String str1="后天要下雨";
System.out.println("指定新内容替换旧的内容:"+str1.replace("下雨","天晴"));

子串

方法声明方法作用
public String subString(int start)指定位置开始截取字符串,直到结尾。[start,length]
public String subString(int start,int end)截取指定范围内的字符串。[start,end]
String str="信息技术有限公司";
System.out.println("指定开始的索引值截取子串:"+str.substring(2));//从2的
System.out.println("指定开始的索引值截取子串:"+str.substring(2,6));//从2到6截取到子串

比较

方法声明方法作用
public int compareTo(String str)按字典顺序进行比较,区分大小写
public int compareToIgnore(String str)按字典顺序进行比较,忽略大小写

拆分

方法声明方法作用
String[] split(String regex)分割字符串为一个字符串数组。通常使用逗号
String str="张三-李四-王五";
String[] arr=str.split("-");
System.out.println("字符串数组的内容:"+Arrays.toString(arr));

将其它数据转换为字符串

修饰方法声明返回值类型
static StringvalueOf(boolean b)返回boolean参数字符串表示形式
static StringvalueOf(char c)返回char参数的字符串表示形式
static StringvalueOf(char[] data)返回char数组参数的字符串表示形式
static Stringvalue(char[] data,int offfset,int count)返回char数组参数的特定子数组的字符串表示形式
static StringvalueOf(double d)返回double参数的字符串表示形式
static StringvalueOf(float f)返回float参数的字符串表示形式
static StringvalueOf(int i)返回int参数的字符串表示形式
static StringvalueOf(long l)返回long参数的字符串表示形式
static StringvalueOf(Object obj)返回Object 参数的字符串表示形式

StringBuffer

  • 为啥需要StringBuffer

  • 因为String内容是不可以被修改的,在频繁操作字符串的应用中,导致String对象泛滥,不断的被创建和销毁,占用大量的内存和cpu空间。

例:

String result="";
for (int i = 0; i < 100; i++) {
    result +="A";
}
  • 这创建了100个对象,其中有99个对象是临时对象,是计算的中间结果。JVM需要花费大量的内存来存放,也需要花费大量cpu时间来收回对象。

  • 因此,通常要使用可变字符串缓冲区类(StringBuffer)来完成类似的工作:

StringBuffer buffer=new StringBuffer(100*1024);
    for(int i=0;i<1000;i++){
        buffer.append("A");
    }
    String result=buffer.toString();
    System.out.println(result);
}
  • 这样,只需要创建一个StringBuffer和一个String对象就完成了

缓冲原理

  • StringBuffer对象内部有一个缓冲区,默认缓冲区的容量是16字节。

  • 通过StringBuffer的append方法向缓冲区中不断追加数据,当数据的大小超过缓冲区的大小时,系统会重新创建一个原来缓冲区的一倍大的新缓冲区,并将原来的缓冲中的数据拷贝到新的缓冲区中,这种操作非常耗资源。因此,需要预估数据所占空大小,在创建缓冲区时就预分配最大值,防止重新创建新缓冲区,提高系统性能

例:将三个字符串连接起来组成一个字符串:

StringBuffer buffer;
String str2="Hello";
String str3="World";
String str4="Beijing";
  • 第一种方法:
String str5=str2+str3;
String str6=str5+str4;
//这种方法是有临时对象str5
  • 第二种方法:使用StringBuffer:
StringBuffer sb=new StringBuffer(1024);//设置初始缓冲区大小
sb.append(str2).append(str3).append(str4);
String str7= sb.toString();//获得结果字符串
  • 只需要创建一个StringBuffer对象,不需要再额外创建对象,最后直接返回缓冲区中的值为一个字符串,这种方法的优点在于,它只需要一次性分配缓冲区,之后就不会再需要创建额外的临时对象,整个性能会非常高

常用方式

  • 先使用StringBuffer创建一个字符串缓冲类,然后使用append增加数据。
StringBuffer sb=new StringBuffer(5*1024);//建立一个长度为5*1024的缓冲区
sb.append("java");
sb.append("java");
sb.append("java");
sb.append("java");
sb.append("java");
System.out.println(sb);//sb.toString()获取字符串

方法

方法声明方法作用
StringBuffer deleteCharAt(int index)删除指定位置的字符,并返回本身
StringBuffer delet(int start,int end)删除从指定位置开始指定位置结束的内容 ,并且返回本身
StringBuffer replace(int start,int end,String str)从start到end用str替换
StringBuffer reverse()字符串反转
String substring(int start)从指定位置截取到末尾
String substring(int start,int end)截取start到end的字符串,包括开始位置,不包括结尾处

添加

方法声明方法作用
StringBuffer()空构造
StringBuffer(int capacity)指定容量的字符串缓冲对象
StringBuffer(String str)指定字符串的内容的字符串缓冲对象
StringBuffer append(xxx)在缓冲区的尾部添加新的文本对象。它支持任意类型的参数,都自动被转换为字符串
StringBufffer insert(int offet,xxx)在指定的索引位置添加新的文本对象
StringBuffer sb=new StringBuffer("jack");
sb.append(true);
sb.append('a');
sb.append(97).append(34.0).append(new char[]{'o','o'});//链式编程
System.out.println(sb.toString());//输出缓冲区中的文本

sb=new StringBuffer("jack");
sb.insert(2,"java");//jajavack
System.out.println(sb.toString());

查看

方法声明方法作用
int capacity()返回当前容量
int length()返回长度(字符数)
indexOf(String str)返回第一次出现的指定字符串在字符串中的索引
String substring(int start)从指定位置截取到末尾
String substring(int start,int end)截取start到end的字符串,包括开始位置,不包括结尾处
toString()返回StringBuffer中的字符串

例:

StringBuffer sb=new StringBuffer("jackc");
System.out.println(sb.indexOf("c"));
System.out.println(sb.length());

修改

方法声明方法作用
StringBuffer replace(int start , int end,String str)使用指定字符串替换字串。[start,end]
setCharAt(int index,char ch)替换指定位置中的字符

例;

StringBuffer sb=new StringBuffer("hellow");
System.out.println(sb.replace(4,7,"java"));
sb.setCharAt(8,'Q');
System.out.println(sb);

删除

方法声明方法作用
StringBuffer deleteChartAt(int index)删除指定位置的字符,并返回本身
StringBuffer delete(int start,int end)删除从指定位置开始指定位置结束的内容,并返回本身

例:

StringBuffer sb=new StringBuffer("helloWorld");
System.out.println(sb.delete(2,5));//heworld
System.out.println(sb.deleteCharAt(2));//heorld

反序

方法声明方法作用
StringBuffer reverse()字符串反转

例:

String str="hellworld";
StringBuffer sb=new StringBuffer(str);
System.out.println(sb.reverse());

String、StringBuffer、StringBuilder的区别

区别是否可变
StringString的值是不可变的,每次对String的操作都会生成新的String对象,浪费空间不可变
StringBufferStringBuffer是可变的,任何对它指向的字符串都不会产生新的对象。可变
StringBuilder可变可变

uffer(str);
System.out.println(sb.reverse());




String、StringBuffer、StringBuilder的区别 

|               | 区别                                                         | 是否可变 |
| ------------- | ------------------------------------------------------------ | -------- |
| String        | String的值是不可变的,每次对String的操作都会生成新的String对象,浪费空间 | 不可变   |
| StringBuffer  | StringBuffer是可变的,任何对它指向的字符串都不会产生新的对象。 | 可变     |
| StringBuilder | 可变                                                         | 可变     |

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

@湖

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

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

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

打赏作者

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

抵扣说明:

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

余额充值