java的字符串存储是直接用String这个引用数据类型的,而非像C语言那样只能用字符数组或者字符指针,更是满足面向对象这一思想。
1. java常量的直接赋值,是直接在栈内开辟内存,用以指向在堆中存在的常量对象。
String arr1 = "abcd";
String arr2 = "abcd";
故相同字符常量可以有多个对象指向
Java的String是引用类型,内部并不存储字符串本身。
若改变字符串的内容,如在上述arr1后加字符串内容
String arr1 = new String("abcd");
arr1 += "ooooo";
System.out.println(arr1);
却不是修改字符串”abcd“本身(在后面加”oooo“),而是重新创建了一个内容为”abcdoooo“的字符串,arr1重新指向该字符串,如图
具体原因如下:
我们看String的源码可知,其字符串实际是存储在用final修饰的char类型数组中,这意味着
String的引用变量不可指向其他对象,但其引用对象的内容可以修改。
String arr1 = "abcd";
String arr1 = new String("abcd");
char[] ch = {'a','b','c','d'};
String arr1 = new String(ch);
引用类型,比较两个对象的地址
String arr1 = new String("abcd");
String arr2 = new String("abcd");
System.out.println(arr1 == arr2); //运行结果:false
内置类型,比较的是两个对象的值
String arr3 = "abcd";
String arr4 = "abcd";
System.out.println(arr3 == arr4); //运行结果:true
语法: 字符串1 .equals(字符串2) 比较方法:按字典序
String 类重写了父类 Object 中 equals 方法(boolean equals(Object anObject))
只比较内容,相同返回true,不同返回false。
String arr1 = new String("abcd");
String arr2 = new String("abcd");
String arr3 = new String("oooo");
System.out.println(arr1.equals(arr2)); //运行结果:true
System.out.println(arr1.equals(arr3)); //运行结果:false
语法: 字符串1 .compareTo(字符串2) 比较方法:按字典序
compareTo 返回的是 int 类型( int compareTo(String s) )
大于返回一个大于0的数字,小于返回小于0的数字,相等返回0。
String arr1 = new String("abcd");
String arr2 = new String("abcd");
String arr3 = new String("oooo");
System.out.println(arr1.compareTo(arr2)); //运行结果:0
System.out.println(arr1.compareTo(arr3)); //运行结果:-14
System.out.println(arr1.compareTo(arr3)); //运行结果:-14
//a(第1位)和 o(第15位) ASCll码序列相差14位
语法: 字符串1 .compareToIgnoreCase(字符串2) 比较方法:按字典序
与compareTo不同的是,其忽略大小写的比较,大于返回一个大于0的数字,小于返回小于0的数字,相等返回0。
String arr1 = new String("abcd");
String arr2 = new String("ABcd");
String arr3 = new String("oood");
System.out.println(arr1.compareToIgnoreCase(arr2)); // 0
System.out.println(arr1.compareToIgnoreCase(arr3)); //-14
System.out.println(arr1.compareToIgnoreCase(arr3)); //-14
常见String查找方法如下:
三种具体: 字符串.charAt( ) 字符串.indexOf( ) 字符串.lastIndexOf( )
String arr1 = "abcda2bc1do1ab2oocdzbc2d";
//不同条件下第一次出现的
System.out.println(arr1.charAt(3)); //下标为3的元素 -> d
System.out.println(arr1.indexOf('d')); //字符d下标 -> 3
System.out.println(arr1.indexOf('d',8)); //字符d从8下标计算的下标 -> 9
System.out.println(arr1.indexOf("ab")); //字符串ab,字符串中下标 -> 0
System.out.println(arr1.indexOf("ab",3)); //字符ab,从下标3开始的下标 ->12
//以下都是从尾巴开始倒着找不同条件下第一次出现的
System.out.println(arr1.lastIndexOf('d')); //字符d,从尾倒着找下标 ->23
System.out.println(arr1.lastIndexOf('d',6)); //字符d,从下标6开始倒着找下标 -> 3
System.out.println(arr1.lastIndexOf("cd")); //字符串cd,从尾开始倒着找下标 -> 17
System.out.println(arr1.lastIndexOf("cd",6)); //字符串cd,从下标6开始倒着找下标-> 2
String arr1 = String.valueOf(123); //int整型
String arr2 = String.valueOf(12.3); //double浮点型
String arr3 = String.valueOf(true); //boolean型
System.out.println(arr1); //123
System.out.println(arr2); //12.3
System.out.println(arr3); //true
int num1 = Integer.parseInt("123");
double num2 = Double.parseDouble("123");
System.out.println(num1); //123
System.out.println(num2); //123.0
String arr1 = "aaa";
String arr2 = "BBB";
System.out.println(arr1.toUpperCase());//转大写 AAA
System.out.println(arr2.toLowerCase());//转小写 bbb
char[] ch = {'a','b','c','d'};
String arr1 = new String(ch);
System.out.println(ch); //abcd
String arr1 = "abcd";
char[] ch = arr1.toCharArray();
for (int i = 0; i <ch.length ; i++) {
System.out.print(ch[i] + " ");
}//a b c d
去掉字符串中的左右空格,保留中间空格
String arr1 = " abc def ";
System.out.println("[" + arr1 + "]"); // [ abc def ]
System.out.println("[" + arr1.trim() + "]"); // [abcdef]
注:替换不修改当前字符串 , 而是产生一个新的字符串
String arr1 = "aaaabbbb";
System.out.println(arr1.replace('a','o')); //将所有字符a替换为o -> oooobbbb
System.out.println(arr1.replaceAll("aa","o"));//将所有字符串aa替换为o -> oobbbb
System.out.println(arr1.replaceFirst("aa","oo"));//将第一个字符串aa替换为oo -> ooaabbbb
可以将一个完整的字符串按照指定的分隔符(如下例子中的空格” “)划分为若干个子字符串,以字符串数组形式存储
String arr1 = "aaaa bbbb cccc";
String[] arrrs1 = arr1.split(" "); //将字符串用空格分割
for (int i = 0; i < arrrs1.length; i++) {
System.out.println(arrrs1[i]);
}
/*
运行结果:aaaa
bbbb
cccc
*/
String[] arrrs2 = arr1.split(" ",2); //将字符串用空格分割为2组
for (int i = 0; i < arrrs2.length; i++) {
System.out.println(arrrs2[i]);
}
/*
运行结果:aaaa
bbbb cccc
*/
注:
如何证明是用字符数组形式存储呢?
String str = "name=zhangsan&age=18" ;
String[] result = str.split("&") ; //第一次拿&分割
for (int i = 0; i < result.length; i++) {
String[] temp = result[i].split("=") ; //第一次拿=分割
System.out.println(temp[0] +" ~ "+ temp[1]);
}
/*运行结果:
name ~ zhangsan
age ~ 18
*/
从一个完整的字符串之中截取出部分内容
String arr1 = "123456789" ;
System.out.println(arr1.substring(2)); //截取下标2到结尾范围的字符串
System.out.println(arr1.substring(0,4)); //截取下标[0,4)范围的字符串
/*运行结果:
3456789
1234
*/
由于 String 的不可更改特性,为了方便字符串的修改, Java 中又提供 StringBuilder 和 StringBuffer 类。
String 和 StringBuilder 最大的区别在于 String 的内容无法修改,而 StringBuilder 的内容可 以修改 。
频繁修改字符串的情况考虑使用 StringBuilder。
StringBuilder sb1 = new StringBuilder("hello");
StringBuilder sb2 = sb1;
//字符串增添
//此处直接当前字符串尾部增添,而非另行创建新字符串
sb1.append(' '); //追加字符 hello
sb1.append("world"); //追加字符串 hello world
sb1.append(123); //追加整型数字 hello world123
System.out.println(sb1 == sb2); //还是指向同一字符串 true
//获取字符串的相关信息
System.out.println(sb1.charAt(0)); // 获取0号位上的字符 h
System.out.println(sb1.length()); // 获取字符串的有效长度 14
System.out.println(sb1.capacity()); // 获取底层数组的总大小
//更改字符串
sb1.setCharAt(0, 'H'); // 设置任意位置的字符 Hello world123
//插入字符串
sb1.insert(0, "Hello world!!!"); // Hello world!!!Hello world123
System.out.println(sb1);
System.out.println(sb1.indexOf("Hello")); // 获取Hello第一次出现的位置
System.out.println(sb1.lastIndexOf("hello")); // 获取hello最后一次出现的位置
//字符串删除
sb1.deleteCharAt(0); // 删除首字符
sb1.delete(0,5); // 删除[0, 5)范围内的字符
//字符串截取
String str = sb1.substring(0, 5); // 截取[0, 5)区间中的字符以String的方式返回
System.out.println(str);
// 字符串逆转
sb1.reverse();
str = sb1.toString(); // 将StringBuffer以String的方式返回
System.out.println(str);
希望对你有帮助。