>  기사  >  Java  >  문자열 소스 코드의 해석 예

문자열 소스 코드의 해석 예

零下一度
零下一度원래의
2017-06-29 09:55:321470검색

String 클래스는 문자열을 저장하기 위해 내부적으로 char[] 유형의 값을 유지합니다. 소스 코드는 비교적 간단합니다.

1. 불변성

String의 불변성은 주로 세 가지 측면에 반영됩니다.

  • String 클래스는 최종 유형으로 정의되며 상속될 수 없습니다.

  • String의 값[]은 final로 정의됩니다

  • String에서 새 문자열을 생성하는 모든 작업은 Array.copy 또는 System.copy를 호출하여 새 String 개체를 생성합니다. 2. 생성자, String의 생성자는 비교적 간단하지만 다음은 더 특별합니다

        public String(String original) {
            this.value = original.value;
            this.hash = original.hash;
        }
        
        String(char[] value, boolean share) {
            // assert share : "unshared not supported";
            this.value = value;
        }
  • 위의 두 가지는 다음과 같습니다. 비교적 특수한 유형의 생성자입니다. 첫 번째는 이미 만들어진 String을 사용하여 새 String 개체를 초기화하는 것입니다. 생성자 메서드는 새 String 개체의 값을 이전 값 개체로 직접 가리킵니다. String은 변경할 수 없으므로 여기에서 값 개체를 다시 복사할 필요가 없습니다. 두 번째 생성자는 String 유형의 불변성을 파괴하는 것처럼 보이지만(매개변수 값이 변경되면 문자열도 변경됨) 이 생성자는 공개로 선언되지 않으며 String()이 공개로 선언된 패키지 내에서만 사용할 수 있습니다. char value[]) 기본 호출은 기본 데이터 복사본을 실현하기 위한 Array.copy입니다. 위의 두 생성자는 더 이상 사용하지 않는 것이 좋습니다.
    public String(char value[], int offset, int count) {
        if (offset < 0) {
            throw new StringIndexOutOfBoundsException(offset);
        }
        if (count < 0) {
            throw new StringIndexOutOfBoundsException(count);
        }
        // Note: offset or count might be near -1>>>1.
        if (offset > value.length - count) {
            throw new StringIndexOutOfBoundsException(offset + count);
        }
        this.value = Arrays.copyOfRange(value, offset, offset+count);
    }
위의 생성자가 더 일반적이며, 다른 많은 생성자는 이와 유사하거나 기본 생성자와 유사합니다. call 생성자가 호출되며 입력 매개변수는 char 배열(byte[]), 오프셋 오프셋 위치 및 카운트 오프셋입니다. 맨 아래 레이어는 Arrays.copy 함수를 호출하여 깊은 복사를 수행합니다.
    public String(StringBuffer buffer) {
        synchronized(buffer) {  //保证线程安全
            this.value = Arrays.copyOf(buffer.getValue(), buffer.length());
        }
    }
    
    public String(StringBuilder builder) {
        this.value = Arrays.copyOf(builder.getValue(), builder.length());
    }

위 두 생성자의 입력 매개변수는 각각 StringBuffer 및 StringBuilder입니다. 유일한 차이점은 StringBuffer가 스레드로부터 안전하고 모든 호출에서 동기화 키워드를 사용해야 한다는 것입니다.

3. 다른 방법

    static int indexOf(char[] source, int sourceOffset, int sourceCount,
            char[] target, int targetOffset, int targetCount,
            int fromIndex) {
        if (fromIndex >= sourceCount) {
            return (targetCount == 0 ? sourceCount : -1);
        }
        if (fromIndex < 0) {
            fromIndex = 0;
        }
        if (targetCount == 0) {
            return fromIndex;
        }

        char first = target[targetOffset];
        int max = sourceOffset + (sourceCount - targetCount);

        for (int i = sourceOffset + fromIndex; i <= max; i++) {
            /* Look for first character. */
            if (source[i] != first) {
                while (++i <= max && source[i] != first);
            }

            /* Found first character, now look at the rest of v2 */
            if (i <= max) {
                int j = i + 1;
                int end = j + targetCount - 1;
                for (int k = targetOffset + 1; j < end && source[j]
                        == target[k]; j++, k++);

                if (j == end) {
                    /* Found whole string. */
                    return i - sourceOffset;
                }
            }
        }
        return -1;
    }
    
    static int lastIndexOf(char[] source, int sourceOffset, int sourceCount,
            char[] target, int targetOffset, int targetCount,
            int fromIndex) {
        /*
         * Check arguments; return immediately where possible. For
         * consistency, don&#39;t check for null str.
         */
        int rightIndex = sourceCount - targetCount;
        if (fromIndex < 0) {
            return -1;
        }
        if (fromIndex > rightIndex) {
            fromIndex = rightIndex;
        }
        /* Empty string always matches. */
        if (targetCount == 0) {
            return fromIndex;
        }

        int strLastIndex = targetOffset + targetCount - 1;
        char strLastChar = target[strLastIndex];
        int min = sourceOffset + targetCount - 1;
        int i = min + fromIndex;

        startSearchForLastChar:
        while (true) {
            while (i >= min && source[i] != strLastChar) {
                i--;
            }
            if (i < min) {
                return -1;
            }
            int j = i - 1;
            int start = j - (targetCount - 1);
            int k = strLastIndex - 1;

            while (j > start) {
                if (source[j--] != target[k--]) {
                    i--;
                    continue startSearchForLastChar;
                }
            }
            return start - sourceOffset + 1;
        }
    }

indexOf 및 lastIndexOf는 주로 index 및 lastIndex 함수의 기본 호출입니다. 코드를 읽어 보면 기본 구현에 특별히 강력한 kmp 알고리즘이 아직 구현되어 있지 않음을 알 수 있습니다. 문자별로 스캔합니다. 그중에서도 lastIndexOf는 비교적 드물게 계속 startSearchForLastChar를 사용합니다.

    public String replace(char oldChar, char newChar) {
        if (oldChar != newChar) {
            int len = value.length;
            int i = -1;
            char[] val = value; /* avoid getfield opcode */

            while (++i < len) {
                if (val[i] == oldChar) {
                    break;
                }
            }
            //如果找不到则返回this
            if (i < len) {
                char buf[] = new char[len];
                for (int j = 0; j < i; j++) {
                    buf[j] = val[j];
                }
                while (i < len) {
                    char c = val[i]; //替换
                    buf[i] = (c == oldChar) ? newChar : c;
                    i++;
                }
                //返回新的String,利用上述包内的非public构造函数
                return new String(buf, true);
            }
        }
        return this;
    }
replace는 String 객체의 한 문자를 다른 문자로 바꾸는 데 사용됩니다. 지정된 문자를 찾을 수 없으면 자체적으로 반환하고 새 String 객체를 생성합니다.

---복구 콘텐츠 종료---

위 내용은 문자열 소스 코드의 해석 예의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.