java源码解析之String类(四)

    /*
     * 返回指定字符第一次出现的字符串内的索引
     */
    public int indexOf(int ch) {
        return indexOf(ch, 0);
    }

    /*
     * 返回指定字符第一次出现的字符串内的索引,以指定的索引开始搜索
     * 其中Character.MIN_SUPPLEMENTARY_CODE_POINT是指字符是小于两个字节的
     */
    public int indexOf(int ch, int fromIndex) {
        final int max = value.length;
        if (fromIndex < 0) {
            fromIndex = 0;
        } else if (fromIndex >= max) {
            // Note: fromIndex might be near -1>>>1.
            return -1;
        }

        if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) {
            // //在这里处理大多数情况(ch是BMP代码点或是一个无效代码点)
            final char[] value = this.value;
            for (int i = fromIndex; i < max; i++) {
                if (value[i] == ch) {
                    return i;
                }
            }
            return -1;
        } else {
            return indexOfSupplementary(ch, fromIndex);
        }
    }

    /*
     * private修饰的私有方法,主要用于处理大于Character.MIN_SUPPLEMENTARY_CODE_POINT的字符
     * 因为在String类中会多次使用,所以封装为私有方法
     */
    private int indexOfSupplementary(int ch, int fromIndex) {
        if (Character.isValidCodePoint(ch)) {
            final char[] value = this.value;
            final char hi = Character.highSurrogate(ch);
            final char lo = Character.lowSurrogate(ch);
            final int max = value.length - 1;
            for (int i = fromIndex; i < max; i++) {
                if (value[i] == hi && value[i + 1] == lo) {
                    return i;
                }
            }
        }
        return -1;
    }

    /*
     * 返回指定字符的最后一次出现的字符串中的索引
     */
    public int lastIndexOf(int ch) {
        return lastIndexOf(ch, value.length - 1);
    }

    /*
     * 返回指定字符的最后一次出现的字符串中的索引,若指定索引就是从指定的索引开始向前搜索的第一个。
     * 若无指定索引,就是从最后一个字符向前搜索到的第一个该字符
     */
    public int lastIndexOf(int ch, int fromIndex) {
        if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) {
            final char[] value = this.value;
            int i = Math.min(fromIndex, value.length - 1);
            for (; i >= 0; i--) {
                if (value[i] == ch) {
                    return i;
                }
            }
            return -1;
        } else {
            return lastIndexOfSupplementary(ch, fromIndex);
        }
    }

    /*
     * 同上一个私有方法,这个用于处理lastIndexOf的非BMP代码点
     */
    private int lastIndexOfSupplementary(int ch, int fromIndex) {
        if (Character.isValidCodePoint(ch)) {
            final char[] value = this.value;
            char hi = Character.highSurrogate(ch);
            char lo = Character.lowSurrogate(ch);
            int i = Math.min(fromIndex, value.length - 2);
            for (; i >= 0; i--) {
                if (value[i] == hi && value[i + 1] == lo) {
                    return i;
                }
            }
        }
        return -1;
    }

    /*
     * 返回指定子串的第一次出现的字符串中的索引,从指定的索引开始。,若不指定索引就是从下标0开始。
     * 方法具体类似于返回指定字符的索引,这个方法返回的是指定字符串中的第一个字符的下标
     */
    public int indexOf(String str) {
        return indexOf(str, 0);
    }

    /*
     * 
     */
    public int indexOf(String str, int fromIndex) {
        return indexOf(value, 0, value.length, str.value, 0, str.value.length, fromIndex);
    }

    /*
     * 
     */
    static int indexOf(char[] source, int sourceOffset, int sourceCount, String target, int fromIndex) {
        return indexOf(source, sourceOffset, sourceCount, target.value, 0, target.value.length, fromIndex);
    }
    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;
    }

    /*
     * 
     */
    public int lastIndexOf(String str) {
        return lastIndexOf(str, value.length);
    }

    public int lastIndexOf(String str, int fromIndex) {
        return lastIndexOf(value, 0, value.length, str.value, 0, str.value.length, fromIndex);
    }
    /*
     * 
     */
    static int lastIndexOf(char[] source, int sourceOffset, int sourceCount, String target, int fromIndex) {
        return lastIndexOf(source, sourceOffset, sourceCount, target.value, 0, target.value.length, fromIndex);
    }

    static int lastIndexOf(char[] source, int sourceOffset, int sourceCount, char[] target, int targetOffset,
            int targetCount, int fromIndex) {
        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;
        }
    }

 

posted @ 2018-07-25 12:34  GolLong  阅读(345)  评论(0编辑  收藏  举报