String修改问题
String存的是引用
为什么String不能被修改内容:
- String是一种不可变对象. 字符串中的内容是不可改变。字符串不可被修改,是因为String类在设计时就是不可改变的,String类实现描述中已经说明了(JDK1,8源码部分),并且String类中的字符实际保存在private维护的value字符数组中,有没有提供修改的API导致不能修改
- value被final修饰表明 string指向得空间不能变,但是指向得空间得内容可更改,即通过下标修改,所以修改能容都是创建了新得对象
如果真要改需要反射 - s+=“world” //也是创建了一个新对象
- String类被final修饰,表明该类不能被继承
- value被修饰被final修饰,表明value自身的值不能改变,即不能引用其它字符数组,但是其引用空间中 的内容可以修改。
- 所有涉及到可能修改字符串内容的操作都是创建一个新对象,改变的是新对象
- 网上有些人说:字符串不可变是因为其内部保存字符的数组被final修饰了,因此不能改变。 这种说法是错误的,不是因为String类自身,或者其内部value被final修饰而不能被修改.final修饰类表明该类不想被继承,final修饰引用类型表明该引用变量不能引用其他对象,但是其引用对象中的内 容是可以修改的,只不过java的String没有提供修改的API导致不能修改
初始化
使用常量串构造
// 使用常量串构造
String s1 = "hello yzy";
System.out.println(s1);
直接newString对象
String s2 = new String("hello yzy");
System.out.println(s1);
使用字符数组进行构造
char[] array = {'h','e','l','l','o','y','z','y'};
String s3 = new String(array);
System.out.println(s1);
判空
isEmpty() //查看是否为空
==比较
java中双等号比较的是地址
== 比较的是变量存储的地址是否一样
比较
String 中如何判断两个值是否相同
java自定义类要重写equals和hashcode
.equals(另一个string) //来比较value是否相等,只有相等和不相等两种情况
compareTo() 比较两个string大小,可以有大于0小于0等于0三种情况
compareToIgnoreCase() //忽略大小写比较
获取
String的查询,不能[]拿取
//返回index位置上字符,如果index为负数或者越界,抛出IndexOutOfBoundsException异常
char charAt(int index)
查找
第一次出现位置
char类型
//返回ch第一次出现的位置,没有返回-1
int indexOf(int ch)
从fromIndex位置开始找char类型第一次出现的位置
//从fromIndex位置开始找ch第一次出现的位置,没有返回-1
int indexOf(int ch, int fromIndex)
string类型
//返回str第一次出现的位置,没有返回-1
int indexOf(String str)
从fromIndex位置开始找string第一次出现的位置
int indexOf(String str, int fromIndex)
最后一次出现位置
char类型
//从后往前找,返回ch第一次出现的位置,没有返回-1
int lastIndexOf(int ch)
从fromIndex位置开始找,从后往前找char第一次出现的位置
//从fromIndex位置开始找,从后往前找ch第一次出现的位置,没有返回-1
int lastIndexOf(int ch, int fromIndex)
string类型
//从后往前找,返回str第一次出现的位置,没有返回-1
int lastIndexOf(String str)
从fromIndex位置开始找,从后往前找string第一次出现的位置
//从fromIndex位置开始找,从后往前找str第一次出现的位置,没有返回-1
int lastIndexOf(String str, int fromIndex)
转换
数字转字符串
String s1 = String.valueOf(1234);
String s2 = String.valueOf(12.34);
String s3 = String.valueOf(true);
String s4 = String.valueOf(new Student("yzy", 19));//这里重写了
System.out.println(s1);
System.out.println(s2);
System.out.println(s3);
System.out.println(s4);
字符串转数字
//注意:Integer、Double等是Java中的包装类型
int data1 = Integer.parseInt("1234");
//int data1=Integer.valueOf("12345") //其底下还是调了parseInt
double data2 = Double.parseDouble("12.34");
System.out.println(data1);
System.out.println(data2);
字符串全转大写
str.toUpperCase() //转大写,有返回值,是个新new的String
把字符串全转为小写
str.toLowerCase() //转小写,有返回值,是个新new的String
字符串转数组
//s.toCharArray(); 为函数
public static void main(String[] args) {
String s = "hello";
// 字符串转数组
char[] ch = s.toCharArray();
for (int i = 0; i < ch.length; i++) {
System.out.print(ch[i]);
}
}
数组转字符串
public static void main(String[] args) {
char[] ch="abcd"
// 数组转字符串
String s2 = new String(ch);
System.out.println(s2);
}
格式化
//以格式化得形式输出
//以C的格式化方式控制精度存取到string里面
String ret2 =String.format("%d,%d",10,20)
String ret2 =String.format("%f,%.2f" ,3.14134,3.14134) ;
String s = String.format("%d-%d-%d", 2023,7,22);
字符串转化成各种类型
String s = "169";
byte b = Byte.parseByte( s );
short t = Short.parseShort( s );
int i = Integer.parseInt( s );
long l = Long.parseLong( s );
Float f = Float.parseFloat( s );
Double d = Double.parseDouble( s );
替换
替换第一个出现的
//替换第一个出现的
String replaceFirst(String regex, String replacement)
String str1 = "ababcabcdabcdeabcdef";
String ret = str1.replaceFirst("ab","ooo"); //替换第一个
System.out.println(ret);
替换所有的
把所有出现的都替换了
//替换所有的指定内容
String replaceAll(String regex, String replacement)
String ret2 = str1.replaceAll("ab","ooo"); //把所有得ab都替换成ooo
System.out.println(ret2);
同把所有出现的都替换了
//string
String ret3 = str1.replace("ab","ooo"); //把所有得都替换
System.out.println(ret3);
//char
String ret4 = str1.replace('a','p'); //把a都替换成p
System.out.println(ret4);
字符串分割
全拆分
//将字符串全部拆分
String[] split(String regex)
将字符串以指定的格式,拆分为limit组
String[] split(String regex, int limit)
案例测试
//全分
String str = "hello world hello bit";
String[] ret1 = str.split(" ");//以空格符分割,以空格分割 返回一个String数组
//固定分组
String[] ret = str.split(" ",2); //以空格分割 分两组 ,output: hello 和world hello bit
for (int i = 0; i < ret.length; i++) {
System.out.println(ret[i]);
}
//有转义的分组
String str2 = "192.168.0.0.1";
String[] ret2 = str2.split("\\."); //想要以.分割,要转义
for (int i = 0; i < ret2.length; i++) {
System.out.println(ret2[i]);
}
//有转义的分组
String str2 = "192\\168\\0\\0\\1"; //linux直接写 192\168\0\0\1
String[] ret2 = str2.split("\\\\");
for (int i = 0; i < ret2.length; i++) {
System.out.println(ret2[i]);
}
//多种情况都可分割
String str2 = "name=zhangsan&age=18";
String[] ret2 = str2.split("=|&"); //有多个分割符得情况,=和&都会分割
for (int i = 0; i < ret2.length; i++) {
System.out.println(ret2[i]);
}
//再分割的情况
String str2 = "name=zhangsan&age=18";
String[] ret2 = str2.split("&");
for (int i = 0; i < ret2.length; i++) {
String[] strings = ret2[i].split("=");
for (String s : strings) {
System.out.println(s);
}
1. 字符"|","*","+"都得加上转义字符,前面加上 "\\" .
2. 而如果是 "\" ,那么就得写成 "\\\\" .
3. 如果一个字符串中有多个分隔符,可以用"|"作为连字符.
4. "//"的由来: '.'点 匹配除“\n”和"\r"之外的任何单个字符。'\'表示转义字符,"\\"会转义成反斜杠,反斜杠本身就是转义符,所有就成了“\.”,在进行转义就是.,所以"\\".实际上是“.”
字符串截取
从指定索引截取到结尾
String substring(int beginIndex)
截取部分内容
String substring(int beginIndex, int endIndex)
测试样例
String str = "helloworld" ;
System.out.println(str.substring(5)); //截取指定位置开始的剩余字符串,从5开始
System.out.println(str.substring(0, 5)); //[0,5),左闭右开
去空格
去除字符串左右空格
去掉字符串中的左右空格,保留中间空格
String str = " hello world " ;
System.out.println("["+str+"]");
System.out.println("["+str.trim()+"]");
获取string长度
s.length();
特殊拼接
int id=1;
String name="yzy";
String sql = "insert into student values("+ id +","+ name +")";
克隆
String a = new String("hello yzy");
String b = a.clone();