Java 常用类之 String 类
8.5、String类
8.5.1、String 的概念
定义:在 java 中的字符串类型
String 类在 java.lang 包下面。
String
类代表字符串。Java 程序中的所有字符串字面值(如“abc”)都作为此类的实例实现。
字符串不变;它们的值在创建后不能被更改。字符串缓冲区支持可变字符串。因为 String 对象是不可变的,它们可以被共享。
字符串是常量;它们的值在创建之后不能更改。字符串缓冲区(StrignBuilder 和 StringBuffer)支持可变的字符串。因为String 对象是不可变的,所以可以共享数据(共享机制)。例如:String str = "abc";
String 的概念:
- String 的值是常量。
- String 对象是不可变的,不能通过赋值的方式修改。
- String 的值是共享的,共享机制。
- 应用场景:一般用在赋值和字符串连接比较少的情况下;如果赋值和字符串连接次数频繁,请使用 StringBuilder/StringBuffer
如何创建 String 字符串对象:
1)创建方式:直接赋值:
语法:String 变量名 = "字符串的值"
;
2)String 的构造方法:
String str = new Strign("初始化的字符串");
String(Strign original)
初始化一个新创建的 String 对象,使其表示一个与参数相同的字符序列:换句话说:新创建的字符串是该参数字符串的副本。
String str = new String();
String()
初始化一个新创建的 String 对象,使其表示一个空字符序列。
案例:
public void test01(){
//通过构造创建字符串对象
byte[] bytes = {'A','B','C'};
String s = new String(bytes);
System.out.println("s = " + s); // ABC
//直接创建
String str = "abc";
//构建字符串对象
String str2 = new String("abc");
//构建空字符串对象
String s1 = new String();
}
8.5.2、String 类面试题
public void test02(){
//T1、判断String 类型的 s1、s2 是否相等
String s1 = "abc";
String s2 = "abc";
//这种 "abc",都在堆中方法区中的常量区中,String s1和s2都指向一个地址值
System.out.println(s1 == s2); //true
System.out.println(s1.equals(s2)); //true
}
@Test
public void test03(){
//T2、下面这句话在内存中创建了几个对象?
String s = new String("abc"); //2个对象,new String 是一个,"abc"是一个并且在字符串常量池中
//换一种情况呢
String str = "abc";
//下面这句话在内存中创建了几个对象?
//这时只创建了 1 个对象,因为"abc"已经在字符串常量池中创建好了,这句话只是创建了new String这一个对象
String ss = new String("abc");
}
@Test
public void test04(){
//T3、判断String 类型的 s1、s2 是否相等
String s1 = "abc";
String s2 = new String("abc");
System.out.println(s1 == s2); //false,s1指向"abc"在常量池中的地址值,s2指向new String 在堆中新开辟的一块内存空间(地址值),而这个地址值则指向"abc"在常量区中的地址值
System.out.println(s1.equals(s2)); //true,s1和s2内容相同
}
题1内存分析
题2内存分析
题3内存分析
8.5.3、String 类型作为形参进行值传递
String 类型,Double,Integer(是基本类型的包装类),比较特殊,每
次传递的时候,这3种类型都会创建新的对象,不指向以前的内存空
间,所以不对实参有影响。
public void test04(){
String str = "你好!";
change(str);
System.out.println(str);
}
public void change(String str){
str = "Hello";
}
在常量池中重新创建了一个"Hello",改变 str 的引用,指向了"Hello"在常量池中的地址值
内存分析:
public void test05(){
//str : 0x0079
//str的引用指向Hello!
String str = "Hello!";
//这里是在常量池中重新创建了一个world!!对象,改变的是str的引用!指向了world!!
//str : 0x0080
str = "world!!";
str += "你好!";
System.out.println(str);
}
8.5.4、Java 常用的字符编码
字符集编码有哪些?
1、中文GB2312编码集 : 规定了中文的编码格式,ASCII码,等。
默认2个字节
2、中文GBK 编码集 : 规定了中文的编码格式,ASCII码,等。
默认2个字节
3、万国码UTF-8编码集 : 国际通用标准: 中文、很多国家的语言、字符、字母、符号,ASCII码...
默认3个字节。
4、ASCII码 : char类型 :字母和字符对应的数字
5、拉丁文iso-8859 : 不支持中文、支持拉丁文,ASCII码 ...
public void test07(){
String str = "中国";
//编码
byte[] bytes = str.getBytes();
System.out.println("bytes = " + Arrays.toString(bytes));
//解码
String s = new String(bytes);
System.out.println("s = " + s);
String s1 = new String(bytes,0,3); //编码字符数组,起始位置,长度
System.out.println("s1 = " + s1); //UTF-8 编码,一个汉字占3个字节
}
8.5.5、编码和解码的概念
编码:把字符串转换成计算机可以识别的符号。
byte[] getBytes() 使用平台的默认字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中。
解码:把计算机的符号转换成字符串格式。
String(byte[] bytes) 通过使用平台的默认字符集解码指定的 byte 数组,构造一个新的 String。
String(byte[] bytes,int offset,int length) 通过使用平台的默认字符集解码指定的 byte 子数组,构造一个新的 String。
案例:
控制台输入一个字符串,任意符号【英文、数字、特殊符号】
统计:大写字母、小写字母、数字和特俗符合的个数
public void test08(){
String str = "ab%!@cd_ui IloveyouYUIE!";
char[] chars = str.toCharArray();
int num1=0,num2=0,num3=0,num4=0; 12345
6、char数组和string互相转换
1) String类型转换为char数组
2) char数组转换成String类型: 使用String类的构造方法
for (char ch : chars){
if(ch >='a' && ch<='z'){
num1++;
}else if(ch>='A' && ch<='Z'){
num2++;
}else if(ch>='0' && ch<='9'){
num3++;
}else{
num4++;
}
}
System.out.println("小写字母个数:"+num1);
System.out.println("大写字母个数:"+num2);
System.out.println("数字个数:"+num3);
System.out.println("其他字符个数:"+num4);
}
8.5.6、char 数组和 String 互相转换
1)String 类型转换为 char 数组
char[] toCharArray() 将此字符串转换为一个新的字符数组
2)cahr 数组转换成 String 类型:使用 String 类的构造方法
String(char[] value) 分配一个新的 String,使其表示字符数组参数中当前包含的字符序列。
String(char[] value, int offset, int count) 分配一个新的 String ,它包含取自字符数组参数一个子数组的字符
参数:
int offset :开始转换的下标/索引
int coun :转换的个数
案例
public void test07(){
String str = "I love you,but you love her!";
char[] chars = str.toCharArray();
System.out.println(Arrays.toString(chars));
}
@Test
public void test09(){
String str = "ab%!@cd_ui IloveyouYUIE!";
char[] chars = str.toCharArray();
System.out.println(Arrays.toString(chars));
//把字符数组转换为字符串
String strs = new String(chars,3,4);
System.out.println(strs);
}
8.5.7、String 类型转换为 char 类型
1)使用 String 类的 charAt() 方法 ----> 推荐使用
char charAt(int index) 返回指定索引处的 char 值。
2)使用 toCharArray()[下标/索引] 转换成 char 数组如何根据索引找位置
public void test10(){
String str = "我爱你!";
char c = str.charAt(1);
System.out.println(c);
System.out.println("===============");
char c1 = str.toCharArray()[2];
System.out.println("c1:"+c1);
}
8.5.8、String 的实例方法
1)拼接字符串
String concat(String str) 将指定字符串连接到此字符串的结尾
2)查询指定的字符串,在原字符串中是否存在,如果存在返回 true ,如果不存在返回 false
boolean contains(charSequence s) 当且仅当此字符串包含指定的 char 值序列时,返回 true
3)验证指定的字符串是否是原字符串的结尾,如果是返回 true ,如果不是返回 false
boolean endwith(String suffix) 测试此字符串是否以指定的后缀结束
4)比较2个字符串的内容
boolean equals(Object anObject) 将此字符串与指定的对象比较
5)比较2个字符串的内容,忽略大小写
boolean equalsIgnoreCase(String anotherString) 将此 String 与另一个 String 比较,不考虑大小写
6)返回指定的字符串,在原字符串中第一次出现处的索引(从0开始)
int indexOf(int ch) 返回指定字符在此字符串中第一次出现处的索引
7)返回指定的字符串,在原字符串中第一次出现指定字符处的索引(从0开始),指定开始搜索的位置
int indexOf(int ch, int fromIndex) 返回在此字符串中第一次出现指定字符处的索引,从指定的索引开始搜索
8)返回指定字符在此字符串中最后一次出现处的索引
int lastIndexOf(int ch) 返回指定字符在此字符串中最后一次出现处的索引
9)返回一个新的字符串,它是此字符串的第一个字符串
String substring(int beginIndex) 返回一个新的字符串,它是此字符串的一个子字符串。
beginIndex - 起始索引(包括)。
String substring(int beginIndex, int endIndex) 返回一个新字符串,它是此字符串的一个字符串。
beginIndex - 起始索引(包括)。
endIndex - 结束索引(不包括)。
10)判断是否为空字符串
boolean isEmply() 当且仅当 length() 为0时返回 true
null 和 "" 的区别:
null 表示的是一个对象的值,而非一个字符串,不指向任何对象,相当于没有任何值
"" 表示的是一个长度为0的空字符串。
null 不分配内存空间; "" 会分配内存空间,指向空字符串的内存空间
public void test05(){
String str = "";
printf(str);
}
public void printf(String str){
//判断:如果str字符串不是空,才打印输出内容。
//null ""
if(str!=null && !str.isEmpty()){
System.out.println("打印输出内容!");
}
}
11)返回字符串的长度
int length() 返回此字符串的长度
12)拆分字符串
String[] split(String regex) 根据给定正则表达式的匹配拆分此字符串
public void test15(){
String str = "中国:美国:韩国:日本:英国:法国";
String[] strs = str.split(":");
System.out.println("strs = " + Arrays.toString(strs));
//strs = [中国, 美国, 韩国, 日本, 英国, 法国]
String str2 = "中国.美国.韩国.日本.英国.法国";
//String[] str2s = str2.split("."); //错误 // . 是调用方法的关键字,不能被识别,想识别需要添加反双斜线\\
String[] str2s = str2.split("\\.");
System.out.println("str2s = " + Arrays.toString(str2s));
}
13)把字符串转换成小写
String toLowerCase() 使用默认语言环境的规则将此 String 中的所有字符都转换为小写
14)把字符串转换成大写
String toUpperCase() 使用默认语言环境的规则将此 String 中的所有字符都转换为大写
15)去除字符串前后的空白
String trim() 返回字符串的副本,忽略前导空白和尾部空白
16)把其他类型参数,转换成字符串类型
static String valueOf(Objext o) 返回某数据类型参数的字符串表示形式
练习:
对字符串:"个.....人.信息.txt" 判断是否符合上传图片的格式要求{"bmp","jpg","png"}。
public void test01(){
String uploadName = "个......人.信息.txt";
String[] uploadImgs = {"bmp","jpg","png"};
//根据最后一个 '.' 的位置来找到文件扩展名
String str = uploadName.substring(uploadName.lastIndexOf('.')+1);
boolean flag = true;
for (String uploadImg : uploadImgs) { //遍历合法后缀
if (str.equalsIgnoreCase(uploadImg)){ //判断文件后缀是否合法
System.out.println("可以!");
flag = false;
break;
}
}
if (flag){
System.out.println("不可以!");
}
}
需求:Scanner获取用户输入一个字符串,“aaavvdfadsfaa",过滤重复字符串。最后输出结果:avdfs。顺序不限制
分析:字符串的替换。
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("请输入:"); // “aaavvdfadsfaa"
String oldStr = input.next(); //保存输入
char[] chars = oldStr.toCharArray(); //把输入的字符串转换成字符数组
String newStr = ""; //定义一个新的字符串为空字符串 ""
for (char aChar : chars) { //遍历原字符数组
if (newStr.indexOf(aChar) == -1){ //如果新字符串中不存在字符数组中的字符
newStr += aChar; //则把不存在的字符拼接到新字符串中
} //存在的字符不要
}
System.out.println(newStr); // avdfs
}
8.5.9、字符串缓冲区
概念:
字符串缓冲区,封装了字符串的操作,可以实现字符串的修改和内容的扩展,更方便的操作字符串。
不需要程序员去手动地扩展空间,自动扩展空间
什么时候使用?
一般在如果经常需要进行字符串的拼接,需要使用字符串缓冲区经常使用的2个类:StringBuffer 和 StringBuilder
区别:
- StringBuffer 是线程安全的,StringBuilder 是线程不安全
- StringBuilder 比 StringBuffer 的效率高
- StringBuilder 是jdk1.5之后才新增的类
StringBuilder 的使用
a)构造方法
StringBuilder() 构造一个不带任何字符的字符串生成器,其初始容量为16个字符
StringBuilder(String str) 构造一个字符串生成器,并初始化为指定的字符串内容
b)实例方法
1)将内容追加到 StringBuilder 中,追加到结尾
StringBuilder append(数据类型 变量名) 将某数据类型参数的字符串表示形式追加到序列
2)返回容量
容量扩展的公式:StringBuilder 对象的长度*2+2
int capacity() 返回当前容量
3)把 StringBuilder 对象转换成字符串对象
String toString() 返回此序列中数据的字符串表示形式
4)删除 StringBuilder 的一段子字符串
StringBuilder delete(int start, int end) 溢出此序列中的子字符串中的字符
start - 起始索引(包含)。
end - 结束索引(不包含)。
5)在某个索引位置的前面插入内容,即取代该索引位置,原索引位置即其后面的字符序列向后移动
StringBuilder insert(int offset, 数据类型 变量名) 将某数据类型参数的字符串表示形式插入此序列中
6)字符序列的长度
int length() 返回长度(字符数)
7)反转字符
StringBuilder reverse() 将此字符串序列用其反转形式取代
案例
public void test07(){
StringBuilder sb = new StringBuilder();
//初始容量是16字符
int capacity = sb.capacity();
System.out.println(capacity);
sb.append(123);
sb.append("java");
sb.append("javascript").append("world");
System.out.println(sb.toString());
int capacity2 = sb.capacity();
System.out.println(capacity2);
System.out.println("============================
==");
StringBuilder delete = sb.delete(0, 3);
System.out.println(delete.toString());
StringBuilder insert = sb.insert(3, "撒浪
嘿");
System.out.println(insert.toString());
System.out.println("============================
==");
StringBuilder reverse = sb.reverse();
System.out.println(reverse.toString());
}
判断用户输入的字符串是不是对称字符串:
public void test08(){
StringBuilder sb = new
StringBuilder("abcbba");
String strsb = sb.toString();
//System.out.println(strsb);
StringBuilder reverse = sb.reverse();
String strrev = reverse.toString();
//System.out.println(strrev);
if(strsb.equals(strrev)){
System.out.println("对称的");
}else{
System.out.println("不对称的");
}
}
本文来自博客园,作者:Thecong,转载请注明原文链接:https://www.cnblogs.com/hwphwc/p/16531501.html