文章目录
String
字符串创建时内存的相关变化
加一个内存变化示意图,希望自己可以更好理解。
String str1 = "hello";
String str2 = "hello";
String str3 = new String("hello");
String str4 = new String("hello");
解析:
String str1 = "hello";
执行后,在栈中生成一个引用str1
的同时也会在常量池中生成一个hello
,并且这个str1
引用指向常量池中的hello
String str2 = "hello";
执行后,会在栈中生成一个str2
,按照常理来说同时也会在常量池中生成一个hello
,但是发现在常量池中已经存在了这个常量,此时这个str2
会指向已经存在的hello
String str3 = new String("hello");
执行后,在栈当中生成一个str3
的引用,并且在堆当中创建一个String
对象,同时str3
指向这个对象String str4 = new String("hello");
执行后,在栈当中生成一个str4
的引用,并且在堆当中创建一个新的String
对象,同时str4
指向这个对象
String常用方法
但凡涉及到区间的方法,那么这个区间是左闭右开[start, end)
方法 | 作用 |
---|---|
int length() | 返回字符串的长度 |
int indexOf(char ch) | 返回字符ch的第一次出现的位置的索引下标,从0开始查询。此方法被 多次重载,也可以从指定位置查询 |
int indexOf(String str) | 返回str子字符串在字符串中第一次出现的位置的索引下标 |
int lastIndexOf(char ch) | 返回字符ch最后一次出现的位置的索引下标 |
int lastIndexOf(String str) | 返回str子字符串在字符串中最后一次出现的位置的索引下标 |
String substring(int beginIndex) | 返回从下标beginIndex位置开始到字符串结束的子字符串 |
String substring(int beginIndex, int endIndex) | 返回从下标beginIndex位置开始到下标endIndex位置结束的子字符串 |
String trim() | 返回去除前后空格的字符串(字符串内部的空格保留) |
boolean equals(Object obj) | 字符串对象调用是比较2个字符串的值是否相等,返回true/false |
String toLowerCase() | 字符串转换为小写 |
String toUpperCase() | 字符串转换为大写 |
char charAt(int index) | 返回字符串中下标为index的字符 |
String[] split(String regex, int limit) | 围绕给定正则表达式的匹配项拆分此字符串,返回字符串数组 |
byte[] getBytes() | 将字符串转换为byte数组 |
package com.sinmu.string;
public class String01 {
/**
* 字符串常用函数
* int length() 返回字符串的长度
* int indexOf(char ch) 返回字符ch的第一次出现的位置的索引下标,从0开始查询
* int indexOf(char ch, int fromIndex)从下标fromIndex下标开始查询
* int indexOf(String str) 返回str子字符串在字符串中第一次出现的位置的索引下标
* int lastIndexOf(char ch) 返回字符ch最后一次出现的位置的索引下标
* int lastIndexOf(String str) 返回str子字符串在字符串中最后一次出现的位置的索引下标
* String substring(int beginIndex) 返回从下标beginIndex位置开始到字符串结束的子字符串
* String substring(int beginIndex, int endIndex) 返回从下标beginIndex位置开始到下标endIndex位置结束的子字符串
* String trim() 返回去除前后空格的字符串(字符串内部的空格保留)
* boolean equals(Object obj) 字符串对象调用是比较2个字符串的值是否相等,返回true/false
* String toLowerCase() 字符串转换为小写
* String toUpperCase() 字符串转换为大写
* char charAt(int index) 返回字符串中下标为index的字符
* String[] split(String regex, int limit) 围绕给定正则表达式的匹配项拆分此字符串,返回字符串数组
* byte[] getBytes() 将字符串转换为byte数组
* @param args
*/
public static void main(String[] args) {
String str = "hello java,我喜欢java";
String str2 = "天呐,This is Upper and lower";
System.out.println("字符串的长度为:"+str.length());
//下面四个函数,区分大小写,如果没有找到就返回-1
System.out.println("字符'j'出现的位置:"+str.indexOf('j'));
System.out.println("字符串\"java\"出现的位置:"+str.indexOf("java"));
System.out.println("字符'j'最后一次出现的位置:"+str.lastIndexOf('j'));//区分大小写,如果没有找到就返回-1
System.out.println("字符串\"java\"最后一次出现的位置:"+str.lastIndexOf("java"));
System.out.println("从6开始,截取下标6之后的所有字符:"+str.substring(6));
System.out.println("从6开始,截取下标9之前的所有字符:"+str.substring(6, 9));//取值区间为[begin, end)
System.out.println("返回去除前后空格的字符:"+str.trim());
System.out.println("转换为小写:"+str2.toLowerCase());//遇到英文就转换,其他的不变
System.out.println("转换为大写:"+str2.toUpperCase());
System.out.println("下标为3的字符:"+str.charAt(3));
}
}
字符串和byte数组之间的相互转换
字符串和byte数组之间的相互转换主要用于网络数据传输
网络数据是二进制字节型的,需要把发送的数据转换为字节型,可以用到getBytes()
方法
windows下默认的是GBK编码,未设置字符集的情况下,若文件编码为utf8,那么会优先转文件编码格式
getBytes()
方法被多次重载,可以返回不同编码集的字节数组
public static void main(String[] args) throws UnsupportedEncodingException {
//字符串和byte数组之间的相互转换
//定义一个字符串
String str = "hello java,我喜欢java";
//转换为字节数组,windows下默认的是GBK编码,未设置字符集的情况下,若文件编码为utf8,那么会优先转文件编码格式
byte[] bytes = str.getBytes();
for (byte i : bytes){
System.out.print(i+" ");
}
//转换为字符串,字符串自带构造方法String(byte[] by)
String s = new String(bytes,"utf8");
System.out.println("\n"+s);
}
StringBuilder
StringBuilder
和String
的区别:String
具有不可变性,而StringBuilder
不具备
那么什么是不可变性呢?
String 对象一旦被创建,则不能修改。
这个"不能修改"是指创建了新的对象,所指向的内存空间不变。
一旦对复杂的字符串做操作时,会产生很多的中间变量,比如
substring()
方法会产生一个中变量,这个变量可能存储在堆中,也有可能存储在常量池中。为了解决频繁操作字符串会生成太多的中间变量的问题,引入了
StringBuilder
的概念
StringBuilder常用函数
/**
* StringBuilder常用函数
* append(String str) append方法被多次重载,可以对不同的数据类型进行添加。功能:在字符串后面进行追加
* replace(int start, int end, String str) 对字符串指定的区间进行替换,替换区间:[start, end)
*/
public static void main(String[] args) {
//使用StringBuilder定义一个字符串
StringBuilder stringBuilder = new StringBuilder("你好");
//在"你好"后面添加内容,变成"你好,java"
stringBuilder.append(",java");
// StringBuilder append = stringBuilder.append(",java");
System.out.println(stringBuilder);
//将字符串修改为"你好,JAVA"
stringBuilder.replace(3,7,"JAVA");//替换区间[start,end)
System.out.println(stringBuilder);
//输出子串JAVA
System.out.println(stringBuilder.substring(3,7));//这个区间为[begin, end)
}
StringBuffer和StringBuilder的区别
- 和
StringBuilder
基本相似 - 不同的地方
StringBuffer
是线程安全的,StringBuilder
则没有- 线程安全与否是的作用对象是多线程
StringBuilder
是单线程的,故而性能略高