zoukankan      html  css  js  c++  java
  • Java基础16-String类(Buffer和Builder)

    一、String类的本质是什么?

     上边代码竟然输出的是一样的,我们进到String类的源码中

    其实,字符串的本质就是字符数组, String 其实就是char数组的封装

    二、字符串的分类

    1.不可变得字符串String:当前对象创建完毕之后,该对象的内容是不能改变的,一旦内容改变就是一个新的类
    2.可变的字符串:StringBuffer/StringBuilder,当前内容创建完毕之后,该对象的内容可以发生改变,内容改变时对象不变

     

    我们输出上边两段代码,虽然引用名称相同,但是当我们重新赋值时,它的hashcode发生了变化,也就是说,str在内存中的地址发生了变化,str="索隆"虽然与str="路飞"名称相同,但实则是两个变量,也就是重新在内存中(常量池)开辟了一块空间

    三、String对象的创建

    1.直接赋一个字面量:
    String str1="abcd";
    2.通过构造器
    String str2=new String("abcd");

     这两者有什么区别呢?别着急,请看下文

    要说这个问题,那就必须要来了解一个内存中的区域,常量池

    常量池:专门存储常量的地方,都指的方法区中
    * 编译常量池:把字节码加载进jvm时,存储的是字节码的相关信息(不研究)
    * 运行常量池:存储常量数据(研究)

    通过这个问题我们就来揭晓 

    String str4="abcd"和String str5=new String("abcd")的区别?

    以上代码创建了几个String对象呢?

    str4最多创建一个,最少不创建,如果常量池中已经存在abcd,直接引用不创建
    str5最多创建两个String对象,至少创建一个,new关键字绝对会在堆空间创建内存区域,所以至少创建一个

    我们再回头看第二种的hashcode不同的问题,实际上就是不同的值在常量池中开辟的空间其地址不同,当值变了。也就是这个引用指向的地址发生了变化

    str和str10的hashcode竟然是一样的! 这下我们就明白了吧,只要是值相同,不管叫什么名字都指向的是同一个地址。

     

    四、String对象的空值
    1.表示引用为空(null):没有初始化,没有分配内存空间
    String str3=null;
    2.内容为空,已经初始化,分配了内存空间,不过没有内容
    五、判断字符串非空
    1.引用不能为空(null)
    2.字符内容不能为空字符串
    六、字符串的比较操作
    1.使用==运算符,只能比较引用的内存地址是否相同
    2.使用equals方法:在object类中和==相同,建议子类覆盖equals方法去比较内容
    七、字符串的比较

    1.单独使用""创建的字符串都是直接量,编译器已经确定存储到常量池中
    2.使用new String("")创建的对象会存储到堆内存中,运行时期才创建
    3.使用只包含直接量的字符串连接符如"aa"+"bb"创建的也是直接量,编译器就能确定,已经存储到常量池中
    4.使用包含String直接量(无final修饰符)的字符串表达式(如"aa"+s1)创建的对象是运行期才创建的,存储在堆中

    八、常用方法联系

        //一、String练习,获取hello开头的文件名的后缀名
        String filename="abc.java;hello.java";
        //1.一份好来分割字符串,获取每个的名称和拓展名
        String[] name=filename.split(";");
        for (String names : name) {
            System.out.println(names);
            //2.判断每个名称是否以hello开头
            if(names.startsWith("hello")) {
                //3.获取文件名的后缀名,最后一个点的后半截
                names.lastIndexOf(".");
                //截取字符串
                System.out.println(names.substring(names.lastIndexOf(".")));
            }
        }
        //二、单词首字母大写
        String str7="willabcad";
        //1.获取第一个字符,转换为大写
        String first=str.substring(0, 1).toUpperCase();
        //2.截取字符串从1到最后
        String last=str.substring(1);
        System.out.println(first+last);
        //trim方法消除前后空格
        System.out.println(" ab cd ".trim().length());
        System.out.println(" ab cd ".length());

    九、StringBuilder和StringBuffer

    先来看一个小例子

        //使用String/StringBuilder和StringBuffer拼接3万次
        long begin=System.currentTimeMillis();
        String str8="";
            for(int i=0;i<30000;i++) {
                str8+=i;
            }
            long end=System.currentTimeMillis();
            System.out.println(end-begin);
            //string做字符串拼接性能很低,原因是每次都要new新的对象
            StringBuffer sb=new StringBuffer("");
            long begin2=System.currentTimeMillis();
                for(int i=0;i<30000;i++) {
                    sb.append(i);
                }
                long end2=System.currentTimeMillis();
            System.out.println(end2-begin2);
            StringBuilder sbr=new StringBuilder("");
            long begin3=System.currentTimeMillis();
            for(int i=0;i<30000;i++) {
                sbr.append(i);
            }
            long end3=System.currentTimeMillis();
        System.out.println(end3-begin3);
            }

    经过测试,sbr耗时最短,sb次之,所以拼接字符串使用stringbuffer或者stringbuilder

    StringBuilder和StringBuffer都表示可变的字符串,功能方法相同
    唯一的区别;
    stringbuffer:使用了synchronized修饰符,表示同步,再多钱程并发时保证线程安全
    stringbuilder:没有synchronized,不安全
    常用操作
    链式编程
    append,deleteCharAt

  • 相关阅读:
    libmysql.lib 和 mysqlclient.lib的区别
    输入框禁止输入法
    html加后退按钮
    spry
    migration
    Ruby char <=> ASCII
    Javascript innerhtml
    My SQL 索引
    datepicker
    ruby 常用正则表达式
  • 原文地址:https://www.cnblogs.com/LuckyGJX/p/9002785.html
Copyright © 2011-2022 走看看