1.创建字符串
常见的构造String的方式
//方式一
String str1 = "helloword";
//方式二
String str2 = new String("helloword");
//方式三
char [] arr = {'h','e','l','l','o','w','o','r','d'};
String str3 = new String (arr);
//执行结果
str1=helloword
str2=helloword
str3=helloword
在这里String是引用类型,“helloword”是字符串字面值常量
内存布局
2.字符串比较
如果现在有两个int型变量,判断其相等可以使用 == 完成。
int x = 10 ;
int y = 10 ;
System.out.println(x == y);
// 执行结果
true
String类对象上使用 ==
String str1 = "Hello";
String str2 = "Hello";
System.out.println(str1 == str2);
// 执行结果
true
/************换一种方式****************/
String str1 = new String("Hello");
String str2 = new String("Hello");
System.out.println(str1 == str2);
// 执行结果
false
代码一内存布局
str1 和 str2 是指向同一个对象的. 此时如 “Hello” 这样的字符串常量是在 字符串常量池 中
代码二内存布局
通过 String str1 = new String(“Hello”); 这样的方式创建的 String 对象相当于再堆上另外开辟了空间来存储"Hello" 的内容, 也就是内存中存在两份 “Hello”.
String 使用 == 比较并不是在比较字符串内容, 而是比较两个引用是否是指向同一个对象.
总结
面向对象编程语言中, 涉及到对象的比较, 有三种不同的方式, 比较身份, 比较值, 比较类型.
在大部分编程语言中 == 是用来比较比较值的. 但是 Java 中的 == 是用来比较身份的.
如何理解比较值和比较身份呢?
取快递场景, 现在取快递, 都有包裹储物柜. 上面有很多的格子. 每个格子里面都放着东西.
例如, “第二行, 左数第五列” 这个柜子和 “第二行, 右数第二列” 这个柜子是同一个柜子, 就是 身份相同. 如果身份
相同, 那么里面放的东西一定也相同 (值一定也相同).
例如, “第一行, 左数第一列” 这个柜子和 “第一行, 左数第二列” 这两个柜子不是同一个柜子, 但是柜子打开后发现
里面放着的是完全一模一样的两双鞋子. 这个时候就是 值相同.
Java 中要想比较字符串的内容, 必须采用String类提供的equals方法.
String str1 = new String("Hello");
String str2 = new String("Hello");
System.out.println(str1.equals(str2));
// System.out.println(str2.equals(str1)); // 或者这样写也行
// 执行结果
true
3.字符串常量池
在JVM底层实际上会自动维护一个对象池(字符串常量池)
如果现在采用了直接赋值的模式进行String类的对象实例化操作,那么该实例化对象(字符串内容)将自动保存到这个对象池之中.
如果下次继续使用直接赋值的模式声明String类对象,此时对象池之中如若有指定内容,将直接进行引用
如若没有,则开辟新的字符串对象而后将其保存在对象池之中以供下次使用
- 理解 “池” (pool)
“池” 是编程中的一种常见的, 重要的提升效率的方式, 我们会在未来的学习中遇到各种 “内存池”, “线程池”, “数据 库连接池”
4.字符串操作
字符串查找
public static void main2(String[] args) {//字符串查找
String str = "abcdefg";
System.out.println(str.contains("ef"));//查找子串
System.out.println(str.indexOf("ef"));//查找包含字串的起始下标 字符串匹配算法KMP
System.out.println(str.indexOf("ef",4));
String str2 = "ababcabcd";
System.out.println(str2.lastIndexOf("ab",4));//从指定位置开始往前找
System.out.println(str2.lastIndexOf("ab"));//从后往前找
System.out.println(str2.startsWith("ab"));
System.out.println(str2.startsWith("ab",2));
System.out.println(str2.endsWith("cd"));//以字符串结尾
字符串拆分
public static void main4(String[] args) {//字符串拆分
String string = "username=zhangsan&password=123";
String[] strings = string.split("&",3);//限制切几份
for (int i = 0; i <strings.length ; i++) {
System.out.println(strings[i]);
}
}
public static void main3(String[] args) {//字符串替换
String str = "abcdabcd";
System.out.println(str.replaceAll("ab", "**"));//返回新的字符串
System.out.println(str.replace("ab", "**"));//两个效果相同
}
字符串替换
public static void main7(String[] args) {
String str = "java30-split#bit";
String [] strings = str.split("-|#");//多个分隔符同时分割
for (int i = 0; i <strings.length ; i++) {
System.out.println(strings[i]);
}
}
public static void main6(String[] args) {
String str = "192*168*1*1";
String [] strings = str.split("\\*");//特殊符号要用转义字符
for (int i = 0; i <strings.length ; i++) {
System.out.println(strings[i]);
}
}
public static void main5(String[] args) {
String str = "192.168.1.1";
String [] strings = str.split(".");
for (int i = 0; i <strings.length ; i++) {
System.out.println(strings[i]);
}
}
字符串截取
public static void main8(String[] args) {//字符串截取
String str = "abcdef";
String str2 = str.substring(2,4);//左闭右开
System.out.println(str2);
}
其他操作方法
public static void main9(String[] args) {
String str = " abcdef de afe fwe ";
System.out.println(str);
System.out.println(str.trim());//去掉左右两边的空格
}
5. StringBuffer 和 StringBuilder
-
String 和 Buffer、Builder区别
-
1.后两者包含了一些String没有的方法,比如reverse方法
-
2.后两者是可变的,String是不可变的 String的每次拼接。都会产生新的对象。后两者拼接后返回的是this
-
3.StringBuffer和StringBuilder的区别
-
StringBuilder和String应用在单线程情况下
-
Buffer的synchronized ()可以保证线程的安全,在多线程情况下使用(开锁关锁消耗时间)
-
4.StringBuilder和String的区别
-
1.String用“+”的拼接会被优化 ,优化为StringBuilder!!
-
2.在循环当中 不可以使用String直接拼接 会产生大量临时对象 包括优化之后的StringBuilder对象
public static void main(String[] args) {//遇见循环在循环外new对象 循环内部append
String str = "abc";
StringBuilder sbl = new StringBuilder();
sbl.append(str);
for (int i = 0; i <10 ; i++) {
str = sbl.append(i).toString();
//str += i;//会产生大量临时变量
}
System.out.println(str);
}
public static void main4(String[] args) {
String str = "abc";
for (int i = 0; i <10 ; i++) {
StringBuilder sbl = new StringBuilder();
str = sbl.append(str).append(i).toString();
//str += i;//会产生大量临时变量
}
System.out.println(str);
}
public static void main3(String[] args) {
String str = "abc";
for (int i = 0; i <10 ; i++) {
str += i;//会产生大量临时变量
}
System.out.println(str);
}
public static void main1(String[] args) {
String str = "abcd";
//多了一些String没有的方法,使用起来会更方便
StringBuffer sbf = new StringBuffer("abcd");
//拼接
System.out.println(sbf.append("hello"));
StringBuilder sbl = new StringBuilder("abcd");
//拼接
System.out.println(sbl.append("hello"));
}