面向对象-字符串
2018-11-23 本文已影响27人
我叫吴智斌
字符串本质及分类
什么是字符串?
把多个字符串连在一起
字符串分类
1.可变字符串(StringBuffer,StringBuilder): 定义好之后,还可以进行修改, 修改是,不会创建新的内存地址 (内存地址不可变)
2.不可变字符串(String): 定义好了,就不能再去改变, 在内存当中不能再去修改了,修改就会创建新的内存地址
字符串的本质
其实它是一个 chat[ ] 类型的数组
private final char value[ ];
String, StringBuffer, StringBuilder 都实现了:CharSequence接口 ,遵守了规范可以使用里面的方法
字符串的两种比较
不可变字符串(String)
String str = "ABC"; 在内存当中不能再去修改了,修改就会创建新的地址
str = "cd";
字符串是放到方法区常量池当中,这里还没讲常量池,先放到堆当中
String创建
1.直接赋值 String str = "ABC";
2.通过构造器来创建 String str = new String("ABC");
字符串对象为空
1.表示引用为空 String str = null; 还没初始化,没有分配内存空间
2.表示空字符串 String str = " "; 已经创建了对象,已经分配了内存,内容为空
字符串的比较
比较两个字符串相不相等
- == 比较两个内存地址是否相等
String str = "ABC";
String str2 = new String("ABC");
if (str == str2) { 比的是对象的地址
System.out.println("相等");
}else {
System.out.println("不相等");
} 不相等
- 使用在object中的一个方法 equals 和 == 相同
因为 String 类覆盖了 equals 方法
1.先去比较对象地址是否相等
2.如果不相等,再去判断是否为String, 是的话再去逐个判断两者的长度相不相等,在判断每一个字符相不相等
if (str.equals(str2)) { 相等
System.out.println("相等");
}else {
System.out.println("不相等");
}
String类覆盖了 equals 方法
建议子类,自己去覆盖此方法,自己在内部当中去根据自己的需求去判断两个值是否相等
字符串创建以及常量池内存分析
常量--->方法区当中有一个常量池
String str = "ABC";
String str3 = "ABC";
System.out.println(str==str3); true
String str2 = new String("ABC");
1.String str = "ABCD"; 局部变量
使用String str = "ABCD";创建字符串
要么创建一个对象,要么不创建
会先到常量池当中看一下有没有该字符串常量
如果说已经有了,就直接使用,不会创建新的字符串常量池地址
如果常量池当中没有的话,就会在常量池当中创建一个对象
2.String str2 = new String("ABCD"); 创建对象
至少得要创建一个对象, 因为使用了new 在堆当中,至少得要创建一个对象
看一下,常量池当中,有没有传入的字符串常量
如果没有的话,会创建一个字符串常量,放到常量池当中
System.out.println(str2); ABCD 会在堆中找到它的创建地址,这个地址会有一个常量引用,所以就把ABCD打印出来了
字符串工具类设计
给一个字符串,判断是否为空,如果为空返回false
不为空就返回一个true
一个方法当中有return 所在的方法 会立即停止执行
定义一个方法
static boolean hasLength(String str) {
if (str != null && !"".equals(str.replace(" ", ""))) {// 不为空
return true;
} // 为空
return false;//一个方法当中有return 所在的方法 会立即停止执行
}
可以直接简写成
static boolean hasLength(String str) {
return str != null && !"".equals(str.replace(" ", ""));
}
在main方法中执行
boolean res = hasLength(s);
System.out.println(res);
把方法抽成一个工具类
public class StringUtils {
private StringUtils() {};
工具类有两种情况:1.单例模式,2.全部方法搞成静态
static boolean hasLength(String str) {
return str != null && !"".equals(str.replace(" ", ""));
}
}
System.out.println(StringUtils.hasLength(s));
字符串拼接性能演示
1.可变字符串(StringBuffer,StringBuilder): 定义好之后,还可以进行修改,
修改是,不会创建新的内存地址 (内存地址不可变)
2.不可变字符串(String): 定义好了,就不能再去改变, 在内存当中不能再去修改了
,修改就会创建新的内存地址
StringBuilder : 方法前面是没有synchronized的 效率 高一些
StringBuffer : 方法前面多了一个synchronized 加锁 更安全
两种方法使用str.append("传入字符串")
速度上:String>StringBuffer>StringBuilder
可变字符串性能高一些,因为内存地址不会改变
做10000字符串拼接测试
public class SystemMethod {
static void testString() {
long begin = System.currentTimeMillis();
String str = "";
for (int i = 0; i <= 10000; i++) {
str += i;
}
long last = System.currentTimeMillis();
System.out.println(last - begin);//10000次 String的花费250毫秒
}
static void testBuilder() {
long begin = System.currentTimeMillis();
StringBuilder str = new StringBuilder();
for (int i = 0; i <= 100000; i++) {
//str += i; StringBuilder 不是用这种方式拼接的
str.append(i);
}
long last = System.currentTimeMillis();
System.out.println(last - begin);//改为10万次 才花费10毫秒
};
static void testBuffer() {
long begin = System.currentTimeMillis();
StringBuffer str = new StringBuffer();
for (int i = 0; i <= 100000; i++) {
str.append(i);
}
long last = System.currentTimeMillis();
System.out.println(last - begin);//改为10万次 才花费10毫秒
};
public static void main(String[] args) {
testString();
testBuilder();
testBuffer();
}
}
可变字符串StringBuilder
public static void main(String[] args) {
创建的可变字符串,初始容量是16
如果超过了,会自动扩容 扩容是 原来容量 * 2 + 2
sb = sb2
因为它的构造器里传了个16 public StringBuilder() {
super(16);
}
可变字符串,本质还是一个char类型的数组
StringBuilder sb = new StringBuilder();
StringBuilder sb2 = new StringBuilder(16);
System.out.println(sb.capacity());//获取sb里面的容量大小
链式变成 append 里面返回的是一个this 返回自身
sb.append("abcdefg").append("123");
sb.append("123");
System.out.println(sb);//abcdefg123123 在原来字符串的基础上进行拼接
删除指定位置的字符
sb.deleteCharAt(1);
System.out.println(sb);//acdefg123123 把b删除了
可变字符转成不可变
String s = sb.toString();
把不可变类型转成可变类型,直接传入字符串到构造器
StringBuilder sb2 = new StringBuilder(s);
字符串的反转
System.out.println(sb2.reverse());//321321gfedca
}
字符串总结