• 字符串拼接


    字符串拼接,之前使用的"字符串"+"字符串"的方式,但是会在字符串常量池中生成大量的字符串对象,因此,在字符串的拼接中,一般使用StringBuffer火StringBuilder。

    首先需要了解为啥字符串常量无法更改,通过查看String类源码,会发现如下代码:

    public final class String
        implements java.io.Serializable, Comparable<String>, CharSequence {
        /** The value is used for character storage. */
        private final char value[];

    可以看到,字符串是通过一个常量数组存储的,这就是无法更改的原因。那为何StringBuffer就可以取得更好的效果呢?在查看StringBuffer的相关源码后:

    /**
         * A cache of the last value returned by toString. Cleared
         * whenever the StringBuffer is modified.
         */
        private transient char[] toStringCache;
    
        /** use serialVersionUID from JDK 1.0.2 for interoperability */
        static final long serialVersionUID = 3388685877147921107L;
    
        /**
         * Constructs a string buffer with no characters in it and an
         * initial capacity of 16 characters.
         */
        public StringBuffer() {
            super(16);
        }
    
        /**
         * Constructs a string buffer with no characters in it and
         * the specified initial capacity.
         *
         * @param      capacity  the initial capacity.
         * @exception  NegativeArraySizeException  if the {@code capacity}
         *               argument is less than {@code 0}.
         */
        public StringBuffer(int capacity) {
            super(capacity);
        }

    再次查找其父类:AbstractStringBuilder的相关源码:

    /**
         * The value is used for character storage.
         */
        char[] value;
    
        /**
         * The count is the number of characters used.
         */
        int count;
    
        /**
         * This no-arg constructor is necessary for serialization of subclasses.
         */
        AbstractStringBuilder() {
        }
    
        /**
         * Creates an AbstractStringBuilder of the specified capacity.
         */
        AbstractStringBuilder(int capacity) {
            value = new char[capacity];
        }

    会发现有几个不同点,第一,它仍然是通过一个数组进行存储,但是,不是final,而且还提供了一个用来缓存的数组;第二,这个数组有一个长度,初始大小为16;

    通过使用append方法拼接字符串,前面也说过,由于数组长度限制了,那拼接时就会超过这个长度,那应该如何解决?

    查看append方法源码:

     @Override
        public synchronized StringBuffer append(Object obj) {
            toStringCache = null;
            super.append(String.valueOf(obj));
            return this;
        }
    
        @Override
        public synchronized StringBuffer append(String str) {
            toStringCache = null;
            super.append(str);
            return this;
        }
     @Override
        public synchronized StringBuffer append(CharSequence s) {
            toStringCache = null;
            super.append(s);
            return this;
        }

    继续查看其父类:

     public AbstractStringBuilder append(String str) {
            if (str == null)
                return appendNull();
            int len = str.length();
            ensureCapacityInternal(count + len);
            str.getChars(0, len, value, count);
            count += len;
            return this;
        }

    查看ensureCapacityInternal()这个方法:

     private void ensureCapacityInternal(int minimumCapacity) {
            // overflow-conscious code
            if (minimumCapacity - value.length > 0)
                expandCapacity(minimumCapacity);
        }
    
        /**
         * This implements the expansion semantics of ensureCapacity with no
         * size check or synchronization.
         */
        void expandCapacity(int minimumCapacity) {
            int newCapacity = value.length * 2 + 2;
            if (newCapacity - minimumCapacity < 0)
                newCapacity = minimumCapacity;
            if (newCapacity < 0) {
                if (minimumCapacity < 0) // overflow
                    throw new OutOfMemoryError();
                newCapacity = Integer.MAX_VALUE;
            }
            value = Arrays.copyOf(value, newCapacity);
        }

    会发现:

    value = Arrays.copyOf(value, newCapacity);也就是说,进行了数组扩容

    StringBuffer和StringBuilder都可以用来拼接字符串,区别是,安全性不同,查看源码后会发现StingBuffer的成员方法均含有关键字“synchronized ”,而StringBuilder没有

    即StringBuffer时线程安全的

  • 相关阅读:
    LDA的整体流程
    java中字符串的用法
    verification Code
    properties
    Hash
    substring的问题
    LDA和PLSA的区别
    Step By Step(Lua环境)
    Step By Step(Lua调用C函数)
    Step By Step(Lua弱引用table)
  • 原文地址:https://www.cnblogs.com/xuhan74520/p/13889057.html
Copyright © 2020-2023  润新知