Java常用类String&StringBuilder

目录

 

String类

1、String概述

2、创建字符串对象方式

3、String常用的方法

4、String的不可变性

5、字符串常量池

StringBuilder 和 StringBuffer

1、概述

2、常用方法

1、insert

2、append

3、replace

4、delete

5、index

6、其他API

3、StringBuffer

4、小结


String类

1、String概述

String 类代表字符串。Java 程序中的所有字符串字面值(如 "abc" )都作为此类的实例实现。 字符串是常量;它们的值在创建之后不能更改。字符串缓冲区支持可变的字符串。因为 String 对象是不可变的,所以可以共享。

String的成员变量

//String的属性值
private final char value[];
//数组被使用的开始位置
private final int offset;
//String中元素的个数
private final int count;
//String类型的hash值
private int hash; // Default to 0
private static final long serialVersionUID = -6849794470754667710L;
private static final ObjectStreamField[] serialPersistentFields =
new ObjectStreamField[0];

String的构造方法

String()
//初始化一个新创建的 String 对象,使其表示一个空字符序列。
String(byte[] bytes)
//通过使用平台的默认字符集解码指定的 byte 数组,构造一个新的 String。
String(byte[] bytes, Charset charset)
//通过使用指定的 charset 解码指定的 byte 数组,构造一个新的 String。
String(byte[] bytes, int offset, int length)
//通过使用平台的默认字符集解码指定的 byte 子数组,构造一个新的 String。
String(byte[] bytes, int offset, int length, Charset charset)
//通过使用指定的 charset 解码指定的 byte 子数组,构造一个新的 String。
String(byte[] bytes, int offset, int length, String charsetName)
//通过使用指定的字符集解码指定的 byte 子数组,构造一个新的 String。
String(byte[] bytes, String charsetName)
//通过使用指定的 charset 解码指定的 byte 数组,构造一个新的 String。
String(char[] value)
//分配一个新的 String,使其表示字符数组参数中当前包含的字符序列。
String(char[] value, int offset, int count)
//分配一个新的 String,它包含取自字符数组参数一个子数组的字符。
String(int[] codePoints, int offset, int count)
//分配一个新的 String,它包含 Unicode 代码点数组参数一个子数组的字符。
String(String original)
//初始化一个新创建的 String 对象,使其表示一个与参数相同的字符序列;换句话说,新创建
的字符串是该参数字符串的副本。
String(StringBuffer buffer)
//分配一个新的字符串,它包含字符串缓冲区参数中当前包含的字符序列。
String(StringBuilder builder)
//分配一个新的字符串,它包含字符串生成器参数中当前包含的字符序列。

2、创建字符串对象方式

直接赋值方式创建对象是在方法区的常量池

String str="hello";//直接赋值的方式

通过构造方法创建字符串对象是在堆内存

String str=new String("hello");//实例化的方式

. 内存图分析

构造方法实例化方式的内存图:String str = new String("Hello");

当我们再一次的new一个String对象时:

两种实例化方式的区别

1. 直接赋值(String str = "hello"):只开辟一块堆内存空间,并且会自动入池,不会产生垃圾。
2. 构造方法(String str= new String("hello");):会开辟两块堆内存空间,其中一块堆内存会变成垃圾被系统回收,而且不能够自动入池,需要通过public String intern();方法进行手工入池。
3. 在开发的过程中不会采用构造方法进行字符串的实例化。

String类对象一旦声明则不可以改变;而改变的只是地址,原来的字符串还是存在的,并且产生垃圾

3、String常用的方法

 

1、String的判断

boolean equals(Object obj):比较字符串的内容是否相同
boolean equalsIgnoreCase(String str): 比较字符串的内容是否相同,忽略大小写
boolean startsWith(String str): 判断字符串对象是否以指定的str开头
boolean endsWith(String str): 判断字符串对象是否以指定的str结尾

2、String的截取

int length():获取字符串的长度,其实也就是字符个数
char charAt(int index):获取指定索引处的字符
int indexOf(String str):获取str在字符串对象中第一次出现的索引
String substring(int start):从start开始截取字符串
String substring(int start,int end):从start开始,到end结束截取字符串。包括start,
不包括end

3、String的转换

char[] toCharArray():把字符串转换为字符数组
String toLowerCase():把字符串转换为小写字符串
String toUpperCase():把字符串转换为大写字符串

4、其他方法

去除字符串两端空格:String trim()
按照指定符号分割字符串:String[] split(String str)

4、String的不可变性

String不可变的好处

  • 可以实现多个变量引用堆内存中的同一个字符串实例,避免创建的开销。
  • 我们的程序中大量使用了String字符串,有可能是出于安全性考虑。
  • 大家都知道HashMap中key为String类型,如果可变将变的多么可怕。
  • 当我们在传参的时候,使用不可变类不需要去考虑谁可能会修改其内部的值,如果使用可变类的话,可能需要每次记得重新拷贝出里面的值,性能会有一定的损失。

5、字符串常量池

常量池表(Constant_Pool table)
Class文件中存储所有常量(包括字符串)的table。这是Class文件中的内容,还不是运行时的内容,不要理解它是个池子,其实就是Class文件中的字节码指令。
运行时常量池(Runtime Constant Pool)

JVM内存中方法区的一部分,这是运行时的内容。这部分内容(绝大部分)是随着JVM运行时候,从常量池转化而来

字符串常量池(String Pool)
这部分也在方法区中,但与Runtime Constant Pool不是一个概念,String Pool是JVM实例全局共享的,全局只有一个。

StringBuilder 和 StringBuffer

1、概述

StringBuilder 是一个可变的字符序列。它继承于AbstractStringBuilder,实现了CharSequence接口。
StringBuffer 也是继承于AbstractStringBuilder的子类;但是,StringBuilder和StringBuffer不同,前者是非线程安全的,后者是线程安全的。

查看源码及API文档

public final class StringBuilder
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence{
}

2、常用方法

1、insert

private static void testInsertAPIs(){
System.out.println("---------- testInsertAPIs -----------");
StringBuilder sbuilder = new StringBuilder();
// 在位置0处插入字符数组
sbuilder.insert(0, new char[]{'a', 'b', 'c', 'd', 'e'});
// 在位置0处插入字符数组。0表示字符数组起始位置,3表示长度
sbuilder.insert(0, new char[]{'A', 'B', 'C', 'D', 'E'}, 0, 3);
// 在位置0处插入float
sbuilder.insert(0, 1.414f);
// 在位置0处插入double
sbuilder.insert(0, 3.14159d);
// 在位置0处插入boolean
sbuilder.insert(0, true);
// 在位置0处插入char
sbuilder.insert(0, '\n');
// 在位置0处插入int
sbuilder.insert(0, 100);
// 在位置0处插入long
sbuilder.insert(0, 12345L);
// 在位置0处插入StringBuilder对象
sbuilder.insert(0, new StringBuilder("StringBuilder"));
// 在位置0处插入StringBuilder对象。6表示被在位置0处插入对象的起始位置(包括),13是
结束位置(不包括)
sbuilder.insert(0, new StringBuilder("STRINGBUILDER"), 6, 13);
// 在位置0处插入StringBuffer对象。
sbuilder.insert(0, new StringBuffer("StringBuffer"));
// 在位置0处插入StringBuffer对象。6表示被在位置0处插入对象的起始位置(包括),12是结
束位置(不包括)
sbuilder.insert(0, new StringBuffer("STRINGBUFFER"), 6, 12);
// 在位置0处插入String对象。
sbuilder.insert(0, "String");
// 在位置0处插入String对象。1表示被在位置0处插入对象的起始位置(包括),6是结束位置(不
包括)
sbuilder.insert(0, "0123456789", 1, 6);
sbuilder.insert(0, '\n');
// 在位置0处插入Object对象。此处以HashMap为例
HashMap map = new HashMap();
map.put("1", "one");
map.put("2", "two");
map.put("3", "three");
sbuilder.insert(0, map);
System.out.printf("%s\n\n", sbuilder);
}

2、append

/**
* StringBuilder 的append()示例
*/
private static void testAppendAPIs() {
System.out.println("------------------- testAppendAPIs -----------------
--");
StringBuilder sbuilder = new StringBuilder();
// 追加字符数组
sbuilder.append(new char[]{'a','b','c','d','e'});
// 追加字符数组。0表示字符数组起始位置,3表示长度
sbuilder.append(new char[]{'A','B','C','D','E'}, 0, 3);
// 追加float
sbuilder.append(1.414f);
// 追加double
sbuilder.append(3.14159d);
// 追加boolean
sbuilder.append(true);
// 追加char
sbuilder.append('\n');
// 追加int
sbuilder.append(100);
// 追加long
sbuilder.append(12345L);
// 追加StringBuilder对象
sbuilder.append(new StringBuilder("StringBuilder"));
// 追加StringBuilder对象。6表示被追加对象的起始位置(包括),13是结束位置(不包括)
sbuilder.append(new StringBuilder("STRINGBUILDER"), 6, 13);
// 追加StringBuffer对象。
sbuilder.append(new StringBuffer("StringBuffer"));
// 追加StringBuffer对象。6表示被追加对象的起始位置(包括),12是结束位置(不包括)
sbuilder.append(new StringBuffer("STRINGBUFFER"), 6, 12);
// 追加String对象。
sbuilder.append("String");
// 追加String对象。1表示被追加对象的起始位置(包括),6是结束位置(不包括)
sbuilder.append("0123456789", 1, 6);
sbuilder.append('\n');
// 追加Object对象。此处以HashMap为例
HashMap map = new HashMap();
map.put("1", "one");
map.put("2", "two");
map.put("3", "three");
sbuilder.append(map);
sbuilder.append('\n');
// 追加unicode编码
sbuilder.appendCodePoint(0x5b57); // 0x5b57是“字”的unicode编码
sbuilder.appendCodePoint(0x7b26); // 0x7b26是“符”的unicode编码
sbuilder.appendCodePoint(0x7f16); // 0x7f16是“编”的unicode编码
sbuilder.appendCodePoint(0x7801); // 0x7801是“码”的unicode编码
System.out.printf("%s\n\n", sbuilder);
}

3、replace

/**
* StringBuilder 的replace()示例
*/
private static void testReplaceAPIs() {
System.out.println("------------------- testReplaceAPIs-----------------
--");
StringBuilder sbuilder;
sbuilder = new StringBuilder("0123456789");
sbuilder.replace(0, 3, "ABCDE");
System.out.printf("sbuilder=%s\n", sbuilder);
sbuilder = new StringBuilder("0123456789");
sbuilder.reverse();
System.out.printf("sbuilder=%s\n", sbuilder);
sbuilder = new StringBuilder("0123456789");
sbuilder.setCharAt(0, 'M');
System.out.printf("sbuilder=%s\n", sbuilder);
System.out.println();
}

4、delete

private static void testDeleteAPIs() {
System.out.println("------------------- testDeleteAPIs -----------------
--");
StringBuilder sbuilder = new StringBuilder("0123456789");
// 删除位置0的字符,剩余字符是“123456789”。
sbuilder.deleteCharAt(0);
// 删除位置3(包括)到位置6(不包括)之间的字符,剩余字符是“123789”。
sbuilder.delete(3,6);
// 获取sb中从位置1开始的字符串
String str1 = sbuilder.substring(1);
// 获取sb中从位置3(包括)到位置5(不包括)之间的字符串
String str2 = sbuilder.substring(3, 5);
// 获取sb中从位置3(包括)到位置5(不包括)之间的字符串,获取的对象是CharSequence对
象,此处转型为String
String str3 = (String)sbuilder.subSequence(3, 5);
System.out.printf("sbuilder=%s\nstr1=%s\nstr2=%s\nstr3=%s\n",
sbuilder, str1, str2, str3);
}

5、index

/**
* StringBuilder 中index相关API演示
*/
private static void testIndexAPIs() {
System.out.println("-------------------------------- testIndexAPIs -----
---------------------------");
StringBuilder sbuilder = new StringBuilder("abcAbcABCabCaBcAbCaBCabc");
System.out.printf("sbuilder=%s\n", sbuilder);
// 1. 从前往后,找出"bc"第一次出现的位置
System.out.printf("%-30s = %d\n", "sbuilder.indexOf(\"bc\")",
sbuilder.indexOf("bc"));
// 2. 从位置5开始,从前往后,找出"bc"第一次出现的位置
System.out.printf("%-30s = %d\n", "sbuilder.indexOf(\"bc\", 5)",
sbuilder.indexOf("bc", 5));
// 3. 从后往前,找出"bc"第一次出现的位置
System.out.printf("%-30s = %d\n", "sbuilder.lastIndexOf(\"bc\")",
sbuilder.lastIndexOf("bc"));
// 4. 从位置4开始,从后往前,找出"bc"第一次出现的位置
System.out.printf("%-30s = %d\n", "sbuilder.lastIndexOf(\"bc\", 4)",
sbuilder.lastIndexOf("bc", 4));
System.out.println();
}

6、其他API

/**
* StringBuilder 的其它API示例
*/
private static void testOtherAPIs() {
System.out.println("----------- testOtherAPIs -----------");
StringBuilder sbuilder = new StringBuilder("0123456789");
int cap = sbuilder.capacity();
System.out.printf("cap=%d\n", cap);
/*
capacity()返回的是字符串缓冲区的容量
StringBuffer( ); 分配16个字符的缓冲区
StringBuffer( int len ); 分配len个字符的缓冲区
StringBuffer( String s ); 除了按照s的大小分配空间外,再分配16个 字符的缓冲区
你的StringBuffer是用字符构造的,"0123456789"的长度是10另外再分配16个字符,所
以一共是26。
*/
char c = sbuilder.charAt(6);
System.out.printf("c=%c\n", c);
char[] carr = new char[4];
sbuilder.getChars(3, 7, carr, 0);
for (int i=0; i<carr.length; i++){
System.out.printf("carr[%d]=%c ", i, carr[i]);
}
System.out.println();
}

3、StringBuffer

和StringBulider用法差不多

4、小结

String、StringBuffer、StringBuilder之间的区别
String 字符串常量
StringBuffer 字符串变量(线程安全)
StringBuilder 字符串变量(非线程安全)
在大多数情况下三者在执行速度方面的比较:StringBuilder > StringBuffer > String

对于三者使用的总结:

  • 如果要操作少量的数据用 = String
  • 单线程操作字符串缓冲区 下操作大量数据 = StringBuilder
  • 多线程操作字符串缓冲区 下操作大量数据 = StringBuffer

 

 

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

寇大大

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

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

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

打赏作者

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

抵扣说明:

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

余额充值