zoukankan      html  css  js  c++  java
  • 第十八天

    相信String这个类是Java中使用得最频繁的类之一,今天就来和大家一起学习一下StringStringBuilderStringBuffer

     

    一、从源码的角度初步了解String

    想要了解一个类,最好的办法就是看这个类的实现源代码,打开这个类的源码文件就会发现String类是被final修饰的:

    进一步分析可以看出几点:

    1String类是final类,也即意味着String类不能被继承,并且它的成员方法都默认为final方法。在Java中,被final修饰的类是不允许被继承的,并且该类中的成员方法都默认为final方法。在早期的JVM实现版本中,被final修饰的方法会被转为内嵌调用以提升执行效率。而从Java SE5/6开始,就渐渐摈弃这种方式了。因此在现在的Java SE版本中,不需要考虑用final去提升方法调用效率。只有在确定不想让该方法被覆盖时,才将方法设置为final

     

    2源码中String类中的成员属性可以看出,String类其实是通过char数组来保存字符串的。

     

     

    3从上面的两个方法可以看出,无论是sub还是concat操作都不是在原有的字符串上进行的,而是重新生成了一个新的字符串对象。也就是说进行这些操作后,最原始的字符串并没有被改变。

      在这里要永远记住一点:

      String对象的任何改变都不影响到原对象,相关的任何change操作都会生成新的对象

      在了解了于String类基础的知识后,下面来看一些在平常使用中容易忽略和混淆的地方。

     

     

    .深入理解StringStringBufferStringBuilder

    1.String str="hello world"String str=new String("hello world")的区别

    import java.util.Objects;
    
    public class Demo {
        public static void main(String[] args) {
        String s1 = "hello";
        String s2 = new String("hello");
        String s3 = "hello";
        String s4 = new String("hello");
        System.out.println(s1 == s2);//false
        System.out.println(s1 == s3);//true
        System.out.println(s2 == s4);//false
        }
    }

    2.StringStringBuffer以及StringBuilder的区别

    StringBuffer以及StringBuilder的功能和String一样都是可以进行字符串的操作。

    既然在Java中已经存在了String类,那为什么还需要StringBuilderStringBuffer类呢?

    那么看下面这段代码:

    import java.util.Objects;
    
    public class Demo {
        public static void main(String[] args) {
            String string = "";
            for (int i = 0; i < 100; i++) {
                string += "hello";// string = string + hello
                //传统的String做字符串拼接,循环100次,new100字符串对象
            }
            System.out.println(string);
        }
    }

    从上面String的源码中我们可以分析出:这句 string += "hello";的过程相当于将原有的string变量指向的对象内容取出与"hello"作字符串相加操作再存进另一个新的String对象当中,再让string变量指向新生成的对象。也就是说这个循环执行完毕new出了10000个对象,试想一下,如果这些对象没有被回收,会造成多大的内存资源浪费。

    再看下面这段代码:

    import java.util.Objects;
    
    public class Demo {
        public static void main(String[] args) {
            StringBuilder sbBuilder = new StringBuilder();
            for (int i = 0; i < 100; i++) {
                sbBuilder.append("hello");
            }
        System.out.println(sbBuilder.toString());
        }
    }

    这断代码和前面的功能一样,但是这里的10000次循环new操作只进行了一次,也就是说只生成了一个对象,append操作是在原有对象的基础上进行的。因此在循环了10000次之后,这段代码所占的资源要比上面小得多。这就是StringstringBuilder的最最主要的区别。

    其实:字符串拼接从jdk5开始编译器就已经完成了自动优化,当String+常量的代码在编译的时候就会自动被优化为new一个StringBuilder,再调用append方法。

    那么有人会问既然有了StringBuilder类,为什么还需要StringBuffer类?查看源代码便一目了然,事实上,StringBuilderStringBuffer类拥有的成员属性以及成员方法基本相同,区别是StringBuffer类的成员方法前面多了一个关键字:synchronized,不用多说,这个关键字是在多线程访问时起到安全保护作用的,也就是说StringBuffer是线程安全的。有关线程的问题,我们讲多线程的时候在详细讲解!

    总结:这三个类是各有利弊,应当根据不同的情况来进行选择使用

    1、循环外字符串拼接可以直接使用String+操作,没有必要通过StringBuilder进行append.

    2、有循环体的话,好的做法是在循环外声明StringBuilder对象,在循环内进行手动append

    不论循环多少层都只有一个StringBuilder对象。

    3、当字符串相加操作较多的情况下,建议使用StringBuilder,如果采用了多线程,则使用StringBuffer

     

     

     

     

     

     

    相信String这个类是Java中使用得最频繁的类之一,今天就来和大家一起学习一下StringStringBuilderStringBuffer

     

    一、从源码的角度初步了解String

    想要了解一个类,最好的办法就是看这个类的实现源代码,打开这个类的源码文件就会发现String类是被final修饰的:

     

    进一步分析可以看出几点:

    1String类是final类,也即意味着String类不能被继承,并且它的成员方法都默认为final方法。在Java中,被final修饰的类是不允许被继承的,并且该类中的成员方法都默认为final方法。在早期的JVM实现版本中,被final修饰的方法会被转为内嵌调用以提升执行效率。而从Java SE5/6开始,就渐渐摈弃这种方式了。因此在现在的Java SE版本中,不需要考虑用final去提升方法调用效率。只有在确定不想让该方法被覆盖时,才将方法设置为final

     

    2源码中String类中的成员属性可以看出,String类其实是通过char数组来保存字符串的。

     

     

    3从上面的两个方法可以看出,无论是sub还是concat操作都不是在原有的字符串上进行的,而是重新生成了一个新的字符串对象。也就是说进行这些操作后,最原始的字符串并没有被改变。

      在这里要永远记住一点:

      String对象的任何改变都不影响到原对象,相关的任何change操作都会生成新的对象

      在了解了于String类基础的知识后,下面来看一些在平常使用中容易忽略和混淆的地方。

     

     

    .深入理解StringStringBufferStringBuilder

    1.String str="hello world"String str=new String("hello world")的区别

    public class Main {         

        public static void main(String[] args) {

            String str1 = "hello world";

            String str2 = new String("hello world");

            String str3 = "hello world";

            String str4 = new String("hello world");

             

            System.out.println(str1==str2);

            System.out.println(str1==str3);

            System.out.println(str2==str4);

        }

    }

    这段代码的输出结果为

     

    2.StringStringBuffer以及StringBuilder的区别

    StringBuffer以及StringBuilder的功能和String一样都是可以进行字符串的操作。

    既然在Java中已经存在了String类,那为什么还需要StringBuilderStringBuffer类呢?

    那么看下面这段代码:

    public class Main {

        public static void main(String[] args) {

            String string = "";

            for(int i=0;i<10000;i++){

                string += "hello";

            }

        }

    }

    从上面String的源码中我们可以分析出:这句 string += "hello";的过程相当于将原有的string变量指向的对象内容取出与"hello"作字符串相加操作再存进另一个新的String对象当中,再让string变量指向新生成的对象。也就是说这个循环执行完毕new出了10000个对象,试想一下,如果这些对象没有被回收,会造成多大的内存资源浪费。

     

    再看下面这段代码:

    public class Main {      

        public static void main(String[] args) {

            StringBuilder stringBuilder = new StringBuilder();

            for(int i=0;i<10000;i++){

                stringBuilder.append("hello");

            }

        }

    }

    这断代码和前面的功能一样,但是这里的10000次循环new操作只进行了一次,也就是说只生成了一个对象,append操作是在原有对象的基础上进行的。因此在循环了10000次之后,这段代码所占的资源要比上面小得多。这就是StringstringBuilder的最最主要的区别。

    其实:字符串拼接从jdk5开始编译器就已经完成了自动优化,当String+常量的代码在编译的时候就会自动被优化为new一个StringBuilder,再调用append方法。

     

    那么有人会问既然有了StringBuilder类,为什么还需要StringBuffer类?查看源代码便一目了然,事实上,StringBuilderStringBuffer类拥有的成员属性以及成员方法基本相同,区别是StringBuffer类的成员方法前面多了一个关键字:synchronized,不用多说,这个关键字是在多线程访问时起到安全保护作用的,也就是说StringBuffer是线程安全的。有关线程的问题,我们讲多线程的时候在详细讲解!

     

     

     

    总结:这三个类是各有利弊,应当根据不同的情况来进行选择使用

    1、循环外字符串拼接可以直接使用String+操作,没有必要通过StringBuilder进行append.

    2、有循环体的话,好的做法是在循环外声明StringBuilder对象,在循环内进行手动append

    不论循环多少层都只有一个StringBuilder对象。

    3、当字符串相加操作较多的情况下,建议使用StringBuilder,如果采用了多线程,则使用StringBuffer

     

     

     

     

     

     

  • 相关阅读:
    Convert between Unix and Windows text files
    learning Perl:91行有啥用? 88 print " ----------------------------------_matching_multiple-line_text-------------------------- "; 91 my $lines = join '', <FILE>;
    Perl:只是把“^”作为匹配的单字:只是匹配每一行的开头 $lines =~ s/^/file_4_ex_ch7.txt: /gm;
    Perl: print @globbing." "; 和 print @globbing; 不一样,一个已经转换为数组元素个数了
    为什么wget只下载某些网站的index.html? wget --random-wait -r -p -e robots=off -U mozilla http://www.example.com wget 下载整个网站,或者特定目录
    正则表达式中 /s 可以帮助“.”匹配所有的字符,包括换行,从而实现【dD】的功能
     是单词边界锚点 word-boundary anchor,一个“”匹配一个单词的一端,两个“”匹配一个单词的头尾两端
    LeetCode103 Binary Tree Zigzag Level Order Traversal
    LeetCode100 Same Tree
    LeetCode87 Scramble String
  • 原文地址:https://www.cnblogs.com/jikebin/p/12623862.html
Copyright © 2011-2022 走看看