Java的字符串

字符串常量池

  • 字符串常量池是Java中的一个特殊区域,用于存储字符串常量,位于堆内存中。

  • 在使用双引号创建字符串常量时,如果该字符串常量不存在,则会添加该字符串到字符串常量池中,并返回对该字符串的引用,如果存在,则直接返回,避免重复的创建。

  • 使用new创建字符串时,String s3=new String(“Hello”); JVM首先是在字符串常量池中找"Hello" 字符串,如果没有创建字符串常量,然后放到常量池中,若已存在,则不需要创建;还会在内存(不是字符串常量池中)上创建一个新的String对象,存储"Hello",并将内存上的String对象引用地址返回

  • 具有不变性。底层使用final来实现(不可被继承)。如果对字符串有什么操作,比如拼接,是直接新建一个字符串,而不是在原来的字符串修改。字符串常量池中的字符串对象是不可变的,一旦创建就不能被修改。

String str1 = "hello";
String str2 = "hello";
String str3 = new String("hello");

System.out.println(str1 == str2); // true,因为两者指向同一个字符串常量池中的对象
System.out.println(str1 == str3); // false,因为str3是在堆内存中创建的新对象

String str1 = "hello"; //str1指向静态区 
String str2 = new String("hello"); //str2指向堆上的对象
String str3 = "hello"; 
String str4 = new String("hello"); System.out.println(str1.equals(str2));//true System.out.println(str2.equals(str4)); //true System.out.println(str1 == str3); //true
System.out.println(str1 == str2); //false System.out.println(str2 == str4); //false
System.out.println(str2 == "hello"); //false str2 = str1; System.out.println(str2 == "hello");//true

String 有没有 length()方法

数组没有 length()方法 ,有 length 的属性。String 有 length()方法。

String 类的常用方法

方法描述
length()返回字符串的长度。
charAt(int index)返回指定索引处的字符。
isEmpty()检查字符串是否为空。
indexOf(String str)返回指定子字符串在此字符串中第一次出现的索引。
lastIndexOf(String str)返回指定子字符串在此字符串中最后一次出现的索引。
substring(int beginIndex)返回一个新的字符串,从指定索引开始直到字符串末尾。
substring(int beginIndex, int endIndex)返回一个新的字符串,从指定的 beginIndex(包括)开始,到指定的 endIndex(不包括)结束。
startsWith(String prefix)检查字符串是否以指定的前缀开头。
endsWith(String suffix)检查字符串是否以指定的后缀结尾。
toLowerCase()将字符串转换为小写。
toUpperCase()将字符串转换为大写。
trim()去除字符串两端的空格。
replace(char oldChar, char newChar)将字符序列中出现的所有 oldChar 替换为 newChar。
replaceAll(String regex, String replacement)使用给定的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串。
equalsIgnoreCase(String anotherString)比较两个字符串,忽略大小写。
split(String regex)根据给定的正则表达式分割字符串为字符串数组。
join(CharSequence delimiter, CharSequence... elements)使用指定的分隔符连接字符串数组或可迭代对象的元素。
valueOf()将其他数据类型转换为字符串。

在使用 HashMap 的时候,为何用String做key

HashMap 内部实现是通过 key 的 hashcode 来确定 value 的存储位置,因为字符串是不可变的,所以当创建字符串时,它的 hashcode 被缓存下来,不需要再次计算,所以相比于其他对象更快

String和StringBuffer、StringBuilder的区别

String(不可变性)
  • String 是不可变的,一旦创建就不能被修改。每次对字符串的操作都会产生一个新的字符串对象。

  • 不可变性带来的好处是线程安全,因为字符串不可变,所以它们可以被多个线程安全地共享,无需额外的同步开销。

  • 不可变性也是字符串常量池的基础,因为相同的字符串常量可以被多个对象共享,节省内存。

  • String类中使用字符数组保存字符串,private final char value[],所以string对象是不可变的。StringBuilder与StringBuffer都继承自AbstractStringBuilder类,在AbstractStringBuilder中也是使用字符数组保存字符串,char[] value,这两种对象都是可变的。

  • AbstractStringBuilder是StringBuilder与StringBuffer的公共父类

  • 每次对String 类型进行改变的时候,都会生成一个新的String对象,然后将指针指向新的String 对象。StringBuffer每次都会对StringBuffer对象本身进行操作,而不是生成新的对象并改变对象引用。

StringBuffer(线程安全)
  • StringBuffer 是可变的,它可以修改其内部存储的字符序列。

  • StringBuffer 的所有公共方法都是同步的,所以它是线程安全的。这意味着多个线程可以安全地同时修改一个 StringBuffer 实例。

StringBuilder(非线程安全)
  • StringBuilder 也是可变的,它与 StringBuffer 类似,但不同的是 StringBuilder 的所有公共方法都不是同步的,因此它不是线程安全的。

  • StringBuilder 在单线程环境下的性能通常比 StringBuffer 更好,因为它不需要同步。因此,如果在单线程环境下使用,通常优先使用 StringBuilder

如何将字符串反转

使用 StringBuilder 或者 stringBuffer 的 reverse() 方法。

// StringBuffer reverse 
StringBuffer stringBuffer = new StringBuffer(); 
stringBuffer.
append("abcdefg"); 
System. out. println(stringBuffer. reverse()); // gfedcba 
// StringBuilder
reverse StringBuilder stringBuilder = new StringBuilder(); stringBuilder. append("abcdefg");
System. out. println(stringBuilder. reverse()); // gfedcba

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值