程序员JavaWeb

面向对象-字符串

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 = " ";    已经创建了对象,已经分配了内存,内容为空

字符串的比较
比较两个字符串相不相等

  1. == 比较两个内存地址是否相等
        String str = "ABC";

        String str2 = new String("ABC");

        if (str == str2) {  比的是对象的地址
            System.out.println("相等");
        }else {
            System.out.println("不相等");
        } 不相等
  1. 使用在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
    }


字符串总结

上一篇下一篇

猜你喜欢

热点阅读