字符串中的库函数,基本上只要对原来的字符串进行修改,基本上返回的都是一个新的对象
我们先来看一个内存布局图:
String s1=new String("hello"); String s2=new String("world"); String s3=s1;
下列程序的输出结果是:输出good和gbc
public class Task { String str=new String("good"); char[] ch={'a','b','c'}; public static void main(String[] args) { Task task=new Task(); task.change(task.str,task.ch); System.out.println(task.str); System.out.println(task.ch); } public void change(String string,char[] ch){ string="testOK"; ch[0]='g'; } }
1)当我们没有调用这个change方法之前,我们的函数的内存布局是这样子的:
2)当我们进行调用这个函数的时候,用形参来进行接受的时候,没有进入到方法之前:
进行接收到的形参会在栈上面开辟一块空间,此时string就指向了之前咱们对上面的String对象,咱们的形参的char[]数组指向的是堆中的0X100
3)进入到方法之后,因为形参的ch和实参的ch都指向同一块内存地址空间,所以形参可以直接根据引用,来进行修改数组的第一块元素位置改成了g
但是此时的string指向了一个新的字符串,所以它指向的字符串对象发生了改变,里面的引用所指向的地址也发生了改变
这就是整个内存变化图,由此可知str引用变量里面所指向的对象的地址并没有发生改变,不是说传递引用就一定可以改变原来的值, 而是说你拿着这个引用都做了一些啥样的事情
String中的一些常见方法
1)字符与字符串
1)public String(char value[])属于构造方法,将字符数组的内容变成字符串
2)public String(char[] value,int offset,int count)属于构造方法,将字符数组的部分内容变成字符串
3)public char charAt(int index)获取指定索引位置的字符
String str="HelloWorld"; for(int i=0;i<str.length();i++){ System.out.print(str.charAt(i)); } //HelloWorld
4)public char[] toCharArray()将字符串变成字符数组返回
String str="HelloWorld"; char[] values=str.toCharArray(); System.out.println(Arrays.toString(values)); //[H, e, l, l, o, W, o, r, l, d]
5)返回格式化字符串
String str=String.format("%s %s 我是中国人","我想飞","我想要找一个好工作"); System.out.println(str);
//1字符数组变成字符串
char[] arr1={'a','b','c'};//不是双引号引起来的,是不会进行入池的
String str=new String(arr1);
//2将部分字节数组的内容变成字符串
String hh=new String(arr1,1,3);
//3字符串变成数组
String str2="world";
char[] arr2=str2.toCharArray();
//4获取到固定位置的索引的字符
String dd=new String("lijiawei");
char ch=dd.charAt(1);
//判断是否是数字字符还有一种方法
char ch='0';
boolean flag=Character.isDigit(ch);
if(flag==false)
{
System.out.println("不是数字字符");
}else{
System.out.println("是数字字符");
}
//判断这个字符是不是字母
char ch='a';
System.out.println(Character.isAlphabetic(ch));
2)字节与字符串
1)public String(byte[] bytes[]):将字节数转化成字符串
2)public String(byte[],int offset,int length)将字节数组中的内容转化成字符串
3)public byte[] getBytes();将字符串以数组的方式来进行返回
4)public byte[] getBytes(String charsetName) throws UnsupportedException 编码转换处理
byte[] 是把String按照一个字节一个字节的来进行处理,这种情况下适合在网络情况下进行传输,数据存储的场景下进行使用,更适合用于二进制数据来进行操作
char[]是把String按照一个字符一个字符的来进行处理,更适合针对文本数据来进行操作,尤其是包含中文
//1字节数组转化成字符串
byte[] arr1={12,34,5,6,7};
String str=new String(arr1)
//2字符串转化成字节数组
String str1="abcdefgh";
byte[] arr=str1.getBytes();
3)字符串的其他方法
1)比较内容:equals()方法-------是一种真假类型的比较,在Object的equals默认是比较的是地址
1.2)调用equals方法的时候,先看看两个对象的地址是否相同,是否指向同一个对象,相同返回true,也就是说判断他们是否指向同一个对象
1.3)在进行判断这两个对象的类型是否是相同的(防止你写了一个字符串引用和数组的引用来进行比较),instance of是判断是否是同一种类型,就是进行判断anObject是否是String类型的对象
1.4)如果说它们的类型相同,把形参的Object类型转化成字符串类型(将他进行向下转型转化成String类型的对象),再次比较它们的长度,长度不同,直接返回false
1.5)最后再循环进行比较他们对应字符的相同性,如果有一个对应的字符不相同,直接返回false
2)忽略大小写的比较ASCIl码值
String str1="abcdefg"; String str2="ABCDEFG"; System.out.println(str1.equalsIgnoreCase(str2));//打印true
还有忽略大小写比较字符串是否相等
String str1="hello"; String str2="Hello"; System.out.println(str1.equals(str2));//false System.out.println(str1.equalsIgnoreCase(str2));//true
3)比较字符串的长度:实现comparable接口,重写compareTo方法1)如果第一个字符和参数的第一个字符不等,结束比较,返回第一个字符的ASCII码差值。
2)如果第一个字符和参数的第一个字符相等,则以第二个字符和参数的第二个字符做比较,以此类推,直至不等为止,返回该字符的ASCII码差值。
3)如果两个字符串不一样长,可对应字符又完全一样,则返回两个字符串的长度差值。
String str3="abcdefg"; String str4="abcdef"; //str1>str2返回的是正数;str1==str2返回的是0;str1<str2返回的是负数 System.out.println(str1.compareTo(str2));//String重写CompareTo方法
public int compareTo(String anotherString) { int len1 = value.length;//先进行获取当前this的字符串的大小 int len2 = anotherString.value.length;//在进行获取到传入的参数的字符串的大小 int lim = Math.min(len1, len2);//获取长度的最小值 char v1[] = value; char v2[] = anotherString.value; int k = 0; while (k < lim) { char c1 = v1[k]; char c2 = v2[k]; if (c1 != c2) { return c1 - c2; } k++; } return len1 - len2; }
字符串的其他方法:
1)public boolean contains(CharSequence s)------判断一个子字符串是否存在,因为本质上String实现了CharSequence接口,只要实现了这个接口,那么数据类型都可以用CharSequence来进行接收
2)public int indexOf(String str)
从头开始进行查找指定字符串的位置,查到了就返回位置的开始索引,查不到就返回-1;
3)public int indexOf(String str,int fromindex)从指定位置开始查找字符串的位置
4)public int LastindexOf(String str)从后向前查找子字符串位置
5)public int LastindexOf(String str,int index)从指定位置从后向前进行查找,找到第一个字符的从前向后的索引位置
6)public boolean startWith(String prefix)是否已指定字符串开头
7)public boolean ensEith(String prefix)是否已指定字符串进行开头
String str="abcabcdef"; System.out.println(str.indexOf("a"));//从头开始找,遇到第一个就结束--->0 System.out.println(str.indexOf('d', 4));//从指定位置开始向后找System.out.println(str.indexOf("abc"));//从前向后开始进行查找0 System.out.println("=============================="); System.out.println(str.lastIndexOf('c'));5 System.out.println(str.lastIndexOf('b'));4 System.out.println(str.lastIndexOf("abc"));3
public static void main(String[] args) {
//运行时的命令行参数,命令行参数会放在args数组里面
for(int i=0;i<args.length;i++){
System.out.println(args[i]);
}
}
字符串的替换:这里面都是默认创建了一个新的String
1)public String replaceAll(String regex,String replacement)替换指定的所有内容
2)public String replaceFirst(String regex,String replacement)替换首个内容
3)public String replace(char ch1,char ch2)将指定字符替换成指定字符,如果ch1=ch2那么直接返回原来的字符串
4)public String replace(String str1,String str2),构成了重载
//1字符串的替换
String str1="ababababababpppphhh";
String ret=str1.replace("ab","123");//这回创建一个新的对象
//替换首个指定字符的字符串
ret=str1.replaceFirst("ab","123");
System.out.println(ret);
//2字符串的截取
String str1="Hello";
String ret=str1.substring(1);//从一号位置开始进行截取,截取后面的字符串
System.out.println(ret);//打印出来的值是llo
ret=str1.substring(1,4);[1,4)从一号位置到四号位置进行字符串的截取
//3去掉字符串两边的空格,但是不可以去掉字符串中间的空格
String str1=" abcdef gh ";
String ret=str1.trim();
System.out.println(ret);
//4查找指定的字符串在原字符串的位置
String str1="abcdefg";
int index=str1.indexOf("abc");
int num=str1.indexOf("def");
System.out.println(index);
System.out.println(num);
//5查找目标字符串是否在源字符串之内
String str1="abcdef";
boolean flag=str1.contains("abcdef");
System.out.println(flag);//打印结果是true
4)字符串进行查找
//1从某个位置开始找
String str1="abcdefghabcdefgh";
int index=str1.indexOf("def",2);//从2号位置开始查询def所在的位置
System.out.println(index);//打印结果是3
//2从后面向前面找
index=str1.lastIndexOf("abc");
System.out.println(index);//打印结果是8
//3判断某个字符串是否以xx开头
String str="abcdef";
boolean flag=str.startsWith("ab");
System.out.println(flag);
//4判断某个字符串是否以指定的偏移量开始
String str="abcdefg";
boolean flag=str.startsWith("abc",0);
System.out.println(flag);
//5判断某个字符串是否以xx结尾
String str1="abcdefg";
boolean flag=str.endswith("abc");
System.out.println(flag);//false;
5)有关于字符串的拆分---返回值是一个字符串数组
1)public String[] split(String regex),将字符串全部进行拆分
2)public String[] split(String regex,int limit),将字符串进行部分拆分,该数组长度就是limit极限,不会进行均匀分割
1)String str1="name=zhangsan&age=19"; String[] arr1=str1.split("&"); for(String[] ret: arr1) { String[] ss= ret.split("="); for(String sss:ss) { System.out.println(sss); } } arr1[0]="name=zhangsan"; arr1[1]="age=19";
2)String str1="abc de f"; String arr1[]=str1.split(" ",2); for(String ret:arr1) { System.out.println(ret); } 如果split()后面加上了一个参数2,那么此时返回的字符串就会分成两组 一组是abc,一组是de f; 如果不加上2这个参数或者说压根就没有参数, 此时就会默认分成三组,一组是abc,一组是de,一组是f;
3)String str1="127.0.0.1"; String[] strings=str1.split("\\."); .号这个字符编译器是无法认清的,所以我们要通过/来进行转义,但是我们还需要对\来进行转义,所以要再加上一个\ for(String hh:strings) { System.out.println(hh); } } }
注意事项:
1)字符"|","*","+","",前面加上"\\"
String str1="127*0*0*1"; String[] strings=str1.split("\\*",7); .号这个字符编译器是无法认清的,所以我们要通过/来进行转义,但是我们还需要对/来进行转义,所以要再加上一个/ for(String hh:strings) { System.out.println(hh); } }
2)如果是"",里面就要写上\\3)如果是一个字符串有多个分隔符,那么我们可以使用|来进行分割
String str1="java300 12&31#hello"; String[] strings=str1.split(" |&|#"); for(String str:strings) { System.out.println(str); } //这里面的的分隔符有很多,包括空格,&,#我们可以使用|来进行分割
4)分割\\要写四个\\\\
String str1="1\\2\\3\\4\\5"; String[] strings=str1.split("\\\\"); for(String s:strings) { System.out.println(s); }
String string="123&8989=90&AAA bbb ccc&BBBB"; String[] strings=string.split(" |=|&"); System.out.println(Arrays.toString(strings)); [123, 8989, 90, AAA, bbb, ccc, BBBB]
SubString方法:字符串的截取
构成重载,当我们给的参数是0,默认会返回原来的字符串,如果index==0,不会产生新对象,否则就会产生新对象
1)public subString(int)-----返回值是String(提取子串),从指定位置开始到结尾位置提取子串
String str1="abcdef"; String str2=str1.substring(0); System.out.println(str2); //此时str2打印的是abcdef
2)public subString(int,int)-----返回值是String(提取子串),从指定范围进行截取子串
3)trim()只会进行截取两边的空格,不会进行截取中间的空格,会保留中间的空格
String str1=" abc bc "; String str2=str1.trim();//返回的仍然是new了一个String对象 System.out.println(str2);
像什么验证码会略大小写比较,在操作输入框的时候自动去除掉空格
4)public String toUpperCase()-----字符串转大写(只针对字母),会把小写字母变成大写
5)public String toLowerCase()-----字符串转小写,只会把大写变成小写
6)public int length()-------求字符串长度
7)public boolean IsEmpty()------字符串是否为空
7)String str1="abcdef";
String str2=str1.toUpperCase();
//将小写字母全部变成大写字母,同理str1.toLowerCase是把所有的的大写字母变成小写字母
System.out.println(str2);
8)判断字符串是否为空.isEmpty()方法
String str1="";
System.out.println(str1.isEmpty());----true
1)在这里面我们要注意String str1="";表示这个str1的引用指向一个空字符串,String str2=null,表示str2不会指向任何对象
2)public String intern()------字符串入池操作
concat()方法,出字符串常量池,自动将字符拼接到字符串的末尾
intern()方法,手动入池,表示最后拼接的对象不会进入到常量池里面,会new一个新的对象
String str1="hello".concat("1");
String str2="hello1";
System.out.println(str1==str2);//falsepublic class DemoKail { public static boolean IsAdmin(String array){ return array.toLowerCase()=="admin"; } public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException { System.out.println(IsAdmin("Admin")); } } 打印结果为false,toLowerCase()底层new了一个对象
将一个整数转化成字符串:
1)这里面注意一下咱们的Integer.toString()也是可以把一个整数转化成字符串
2)String.valueOf()是将整数转化成字符串,但是Integer.valueOf()是自动拆箱操作,是将一个包装类型转化成基本数据类型类型,也可以将字符串转化成整数
String str1=Integer.toString(10); String str2=String.valueOf(20);
3)我们也是可以将一个自定义类型的数据转化成字符串:
public static String valueOf(Object obj) { return (obj == null) ? "null" : obj.toString(); }
class Student{ public String username; public String password; public Student(String username, String password) { this.username = username; this.password = password; } @Override public String toString() { return "Student{" + "username='" + username + '\'' + ", password='" + password + '\'' + '}'; } }
Student student=new Student("李佳伟","123456"); System.out.println(String.valueOf(student));
将字符串转化成整数:
int c=Integer.valueOf("8989");