荐 Java基础之字符串String详细解释
目录
栈:基础的数据类型变量以及对象的引用
堆:存放new出来的对象
常量池:字符串常量
字符串常量不可变
底层原码中使用final修饰 char[] value来存储字符串的值。字符串常量是存在常量池
中,一旦声明,就不可以改变,同时常量池中不会存储相同内容的字符串,即s1与s2是相等的。
String s1 = "aaa";
s1 = "bbb";
System.out.println(s1);
String s1 = "123";
String s2 = "123";
System.out.println(s1==s2);
输出的s1的值是bbb,不是改变了么?注意这里的s1是引用对象,因此s1存在栈空间中,也就是s1与aaa并不存在同一内存空间中,只是中间连接了一条绳子将aaa指向了s1,现在这条绳子由bbb指向了s1,但是aaa其实还留在了常量池中,所以说字符串常量是不可改变的。
除此之外,String还实现了Serializable接口,表示字符串可以被序列化,还实现了Comparable接口表示字符串可以比较大小
null," "的区别
String s1 = null
String s2 = ""
- null代表的是
空对象
,并不是字符串,可以赋给任何对象,字符串中表示只是一个引用,还没有内存空间的分配 - “ ”表示引用已经指向了 一块内存空间了,是一个实际的东西,可以进行操作了,表示一个长度为0的字符串
数组转成字符串(String的构造)
-
String():构造一个空的字符串
-
String(byte[] arr): 将字节数组变为一个字符串
-
String(byte[] arr, int offset, int lengh): 将字节数组部分变为字符串
-
String(char[] arr): 将char字节数组变为字符串
-
String(char[] arr, int offset, int length): 将char字节数组部分变为字符串
-
String(String original): 字符串常量构建字符串
byte[]===>String
- 全部转换:转换所有byte数据
byte[] b = {97,98,99,100};
String str = new String(b);
System.out.println(str);//abcd
- 部分转换: 截取转换,超出索引,报出
StringIndexOutOfBoundsException
异常,通常Java中数组索引区间左开右闭的
byte[] b = {97,98,99,100};
String str = new String(b,1,3);
System.out.println(str);//bc
char[]转String等等一些数组转String的方式都和上述大同小异,这些都是对String方法使得构造
==与equals()的比较字符串是否相等
- == 比较的地址和内容都相等才相等
- equals()内容相等即是相等
理解上面两句:
String s1 = "123";①
String s2 = "123";②
String s3 = new String("123");③
System.out.println(s1==s2);//正确
System.out.println(s1==s3);//错误
只要明白了内存分布,判断不成问题。对于①,②来说,上面已经解释过了都在栈内存中,对于③来说,s3是对象存在Java堆中,s1,s2都是存在Java栈中,所以s1==s3是错误的!!!对于equals()就不一样了三者内容都是相等的。
练习一:
String s1 = new String("hello");
String s2 = new String("hello");
System.out.println(s1==s2);
System.out.println(s1.equals(s2));
String s3 = new String("hello");
String s4 = "hello";
System.out.println(s3==s4);
System.out.println(s3.equals(s4));
String s5 = "hello";
String s6 = "hello";
System.out.println(s5==s6);
System.out.println(s5.equals(s6));
答案:F T F T T T
字符串的拼接
- 常量与常量的拼接还在常量池中
- 常量池不可有相同的常量
- 拼接的时候,只要存在变量都会存到堆中
- 调用intern()方法返回常量池里面的常量
String s1 = "hello";
String s2 = "world";
String s3 = "helloworld";
System.out.println(s3==(s1+s2));//F 变量的连接存在堆中不相等
System.out.println(s3==(s1+s2).intern());//T 获取的是值相等
System.out.println(s3.equals(s1+s2));//T 获取内容相等
System.out.println(s3=="hello" + "world");//T 常量与常量连接还在常量池中
System.out.println(s3.equals("hello"+"world"));//T 内容相等
字符串操作常用方法
字符串的判断:
- equals方法比较两个字符串内容是否相等
- equalsIgnorecase忽略大小写比较两个对象是否相等
- contains是否包含字符串
- startsWith()是否以指定的字符串开头
- endsWIth()是否以指定的字符串结尾
- isEmpty()是否为空
String s1 = "abcde";
String s2 = "AbCde";
String s3 = "abcde";
//equals
System.out.println(s1.equals(s2));//t
System.out.println(s1.equals(s3));//f
//equalsIgnorecase
System.out.println(s1.equalsIgnoreCase(s2));//t
System.out.println(s1.equalsIgnoreCase(s3));//t
//是否包含指定字符串
System.out.println(s1.contains("bd"));//f
//是否以指定字符串开头
System.out.println(s1.startsWith("ab"));//t
System.out.println(s1.startsWith("cde",2));//t 字符串是否在索引2开始截取
//是否以字符串结尾
System.out.println(s1.endsWith(s3));//t
//是否为空
System.out.println(s1.isEmpty());//false
字符串的获取
- length():字符串的长度
- charAt(inx index):返回某个字符在字符串中的索引
- indexOf(int ch):获取指定的字符在字符串第一次出现的位置,可以写对应的ASCALL码值
- indexOf(int ch, int fromIndex):从指定的索引开始,字符出现的位置
- indexOf(String str):获取指定的字符串在原字符串的位置
- indexOf(String str, int fromIndex):从指定的索引开始,获取字符串第一次出现的位置
- lastIndexOf(int ch):获取指定字符最后一次出现的索引值
- lastIndexOf(String str,int fromIndex)获取指定字符串最后出现的索引值
- subString(int start):从指定位置开始截取字符串
- subString(int start, int end)从指定位置到指定位置截取字符串
注意:如果没有找到都会返回-1
练习:
String str = "abcdeababcdacaeca";
//长度
System.out.println(str.length());//17
//获取第二个元素
System.out.println(str.charAt(1));//b
//获取最后一个元素值
System.out.println(str.charAt(str.length() - 1));//a
//获取'a'第一次的索引值
System.out.println(str.indexOf('a'));//0
System.out.println(str.indexOf(97));//0
//从第二个索引值开始,'a'第一次出现的位置
System.out.println(str.indexOf('a', 2));//5
//获取"bc"第一次出现的索引值
System.out.println(str.indexOf("bc"));//1
//从2索引开始"ad"第一次出现的索引值
System.out.println(str.indexOf("ad", 2));//-1
//获取'a'最后一次存储的索引值
System.out.println(str.lastIndexOf('a'));//16
//获取'bc'最后一次出现的索引值
System.out.println(str.lastIndexOf("bc"));//8
//从7索引结束前获取'a'最后一次索引值
System.out.println(str.lastIndexOf('a', 7));//7
System.out.println(str.lastIndexOf('c', 6));//2
//从索引5截取到末尾
String s1 = str.substring(5);
System.out.println(s1);//ababcdacaeca
//"abcdeabca" ===> "deab"
String s2 = str.substring(3, 7);
System.out.println(s2);
转换功能
- byte[] getBytes():将字符串转换为字节数组
- byte[] getBytes(String charset):通过指定的字符集,将字符串转成字节数组
- char[] toCharArray():将字符串转成字符数组
- static valueOf(char[] chs):将字符数组转成字符串
- static valueOf(int num):将int数据转成字符串
- static valueOf(Object obj):将任意的引用数据转成字符串
- toLowerCase():转成小写
- toUpperCase():转成大写
- concat(String str):字符串连接
- trim():去除两边空格
tips:不同编码方式汉字占用的字节不同,GBK编码,一个汉字字符占用2个字节,UTF-8编码中一个字符占用3个字节
String s = "Ab三上悠亚";
//String转为byte[]
byte[] bys =s.getBytes();
//[65, 98, -28, -72, -119, -28, -72, -118, -26, -126, -96, -28, -70, -102]
System.out.println(Arrays.toString(bys));
//String转为char[]
char[] c = s.toCharArray();
//[A, b, 三, 上, 悠, 亚]
System.out.println(Arrays.toString(c));
//其它大部分类型转String
System.out.println(String.valueOf(100));//100
System.out.println(String.valueOf(false));//false
System.out.println(String.valueOf('a'));//a
System.out.println(String.valueOf(3.23f));//3.23
System.out.println(String.valueOf(c,0,3));//Ab三 从0索引开始截取三个字符
char[] data = {'A','B','c'};
System.out.println(String.valueOf(data));//ABc
System.out.println(s.toLowerCase());//ab三上悠亚
System.out.println(s.toUpperCase());//AB三上悠亚
字符串的比较和替换
- replace(char old, char new):新的字符替换新的字符
- replace(String old, Stringnew):新的字符串替换新的字符串
- String replace(CharSequence target, CharSequence replacement):替换指定的字符序列
- int compareTo(String str):字典比较字符串
- int compareToIgnoreCase(String str):忽略大小写比较
字符串的替换:
String s = "abc三上悠亚abc";
//b替换B 字符替换
String s1 = s.replace('b', 'B');
System.out.println(s1);//aBc三上悠亚aBc
//三上悠亚替换为JAPAN字符串替换
String s2 = s.replace("三上悠亚", "JAPAN");
System.out.println(s2);//abcJAPANabc
//替换指定的字符序列
String s4 = "abc";
String s5 = "abcd";
String s6 = s.replace(s4, s5);
System.out.println(s6);//abcd三上悠亚abcd
字典比较
字符串是英文并且长度不一样
-
长度长的包含长度短的(这个包含表示从第一个字符开始匹配)直接是长度相减
String str1 = "abcde"; String str2 = "abc"; System.out.println(str1.compareTo(str2));//2
相当于
s1.length() - s2.length()
-
长度不一样,且从第一个字符开始找,没有匹配,则是两个字符ASCALL的差值
String str1 = "abcde"; String str2 = "cabc"; System.out.println(str1.compareTo(str2));//-2
相当于a-c=-2
-
长度一样且不匹配,单个字符ascall值相减即可,多个字符不一样从第一个字符找,如果第一个字符一样比较第二个字符,依次类推…直到不一样时,ASCALL码值相减即可。
String str1 = "cdea"; String str2 = "cdeb "; System.out.println(str1.compareTo(str2));//-1
中文与英文类似!!!
编码与解码
编码:将看懂的变为看不懂的
解码:将看不懂的变为看懂的
String s1 = "我爱china"; byte[] c = s1.getBytes(); //默认为UTF-8,占用3个字节 //[-26, -120, -111, -25, -120, -79, 99, 104, 105, 110, 97] System.out.println(Arrays.toString(c)); byte[] bys = s1.getBytes("GBK"); //指定用GBK进行编码 //[-50, -46, -80, -82, 99, 104, 105, 110, 97] System.out.println(Arrays.toString(bys)); //对c进行解码 String s = new String(c); System.out.println(s); //对bys进行解码 String s2 = new String(bys,"gbk"); System.out.println(s2); //解码错误出现乱码 String s3 = new String(bys,"utf-8"); System.out.println(s3);
运行图:
本文地址:https://blog.csdn.net/qq_41857955/article/details/107349798