• Java中的String,StringBuffer和StringBuilder


    在了解这个问题的时候查了不少资料,最有帮助的是这个博文:http://swiftlet.net/archives/1694,看了一段时间,咀嚼了一段时间,写一个经过自己消化的博文,希望能帮到大家。

    首先,String,StringBuffer,和StringBuilder都是对char[]的封装,而不同点在于String可以被认为是字符串常量,而StringBuffer,StringBuilder则是字符串变量。

    String的成员变量如下:

    1 private final char value[];
    2 private final int offset;
    3 private final int count;

    注意到char value[]是final的,代表着对象一旦被创建就不可改。我们平时常对String执行类似如下操作看起来更改字符串比较自由随意,但是其本身是不断创建新对象的过程:

    String a="Hello World";
    a=a+"!";
    System.out.println(a);
    //result: Hello World!

    所以,对String执行这种经常修改字符串的操作是效率低下的。

    与String不同,StringBuffer和StringBuilder都继承于AbstractStringBuilder,所以我们从AbstractStringBuilder看起

    其中成员变量如下

    1 char value[];
    2 int count;

    首先不是final的,其次这个类引入了很多对“容量”控制的方法,很像C++中的<Vector>

    例如扩容:当添加字符的长度使得char value[]超出了其本身的最大大小,需要创建一个更大的char[]并将内容复制:

     1 void expandCapacity(int minimumCapacity) 
     2 {
     3     int newCapacity = (value.length + 1) * 2;
     4         if (newCapacity < 0) 
     5         {
     6             newCapacity = Integer.MAX_VALUE;
     7         } else if (minimumCapacity > newCapacity)
     8         {
     9         newCapacity = minimumCapacity;
    10     }    
    11     char newValue[] = new char[newCapacity];
    12     System.arraycopy(value, 0, newValue, 0, count);
    13     value = newValue;
    14  }

    同样,char[]不可能所有容量都被使用,结束标识符同C一样是“”;

    补长或者截断:

     1 public void setLength(int newLength) 
     2 {
     3     if (newLength < 0)
     4         throw new StringIndexOutOfBoundsException(newLength);
     5     if (newLength > value.length)
     6         expandCapacity(newLength);
     7     if (count < newLength)
     8         {
     9         for (; count < newLength; count++)
    10         value[count] = '';
    11      } else 
    12          {
    13             count = newLength;
    14          }
    15  }

    内存复制的方法常用的是:

    public static native void arraycopy(Object src, int  srcPos, Object dest, int destPos, int length);

    那么StringBuffer和StringBuilder有什么区别:先从StringBuffer和StringBuilder到String的转换看起:

     1 public String(StringBuffer buffer)
     2 {
     3     synchronized(buffer)
     4     {
     5       this.value = Arrays.copyOf(buffer.getValue(), buffer.length()); }
     6   }
     7 public String(StringBuilder builder)
     8 {
     9     this.value = Arrays.copyOf(builder.getValue(), builder.length());
    10 }

    可见,对于StringBuffer而言,处处要考虑其在多线程环境下的并发问题。也就是说,相比于StringBuilder而言,StringBuffer是线程安全的。

    另外,关于String的intern方法,是将字符串常量放在一个由String类维护的常量池中。当调用intern 方法时,如果池中已经包含一个等于此String 对象的字符串(是否相等由 equals(Object)方法确定),则返回池中的字符串引用。否则,将此 String 对象添加到池中,并且返回此String 对象的引用。例如:对于任何两个字符串s和t,当且仅当s.equals(t)为true时,s.intern()==t.intern()才为true。

  • 相关阅读:
    在IIS上部署 .Net Core 3.0 项目踩坑实录
    .net core3.0部署Linux服务器 使用Docker容器和Nginx反代理教程
    播放器 AxWindowsMediaPlayer控件的使用
    Github下载慢和下载过程中断等情况的解决方案
    GitHub第一次上传遇到的问题
    DataGridView && 增加复选框(checkbox)方法
    努力
    绘图:drawImage一个用法
    Tuple<T1,T2,.........T> 元组简单使用
    随机的标识符GUID
  • 原文地址:https://www.cnblogs.com/lumaoxin/p/7826941.html
Copyright © 2020-2023  润新知