zoukankan      html  css  js  c++  java
  • java源码解析之String类(五)

        /*
         * 切片函数,非常重要,这里一定要牢记beginIndex是开始位置,endIndex是结束位置,区别于以前学的offset是开始位置,而count或length是个数和长度
         * 比如说,new String("abcdefg",1,3)得到的是bcd
         * 而 "abcdefg".substring(1,3)得到的是bc,也就是下标为1和2的俩个字符,并不包括c
         */
        public String substring(int beginIndex) {
            if (beginIndex < 0) {
                throw new StringIndexOutOfBoundsException(beginIndex);
            }
            int subLen = value.length - beginIndex;
            if (subLen < 0) {
                throw new StringIndexOutOfBoundsException(subLen);
            }
            return (beginIndex == 0) ? this : new String(value, beginIndex, subLen);
        }
        public String substring(int beginIndex, int endIndex) {
            if (beginIndex < 0) {
                throw new StringIndexOutOfBoundsException(beginIndex);
            }
            if (endIndex > value.length) {
                throw new StringIndexOutOfBoundsException(endIndex);
            }
            int subLen = endIndex - beginIndex;
            if (subLen < 0) {
                throw new StringIndexOutOfBoundsException(subLen);
            }
            return ((beginIndex == 0) && (endIndex == value.length)) ? this : new String(value, beginIndex, subLen);
        }
    
        /*
         * 返回的是一个字符序列CharSequence,而CharSequence是一个接口,所有这里需要的是CharSequence的实现类
         * 而String实现的最后一个接口就是CharSequence,所以其实这里返回的就是String对象
         * 但是这是一个多态对象,他能调用的方法只有CharSequence接口中的几个,所以此方法没用,除非程序就需要一个CharSequence对象
         * 
         */
        public CharSequence subSequence(int beginIndex, int endIndex) {
            return this.substring(beginIndex, endIndex);
        }
    
        /*
         * 将指定的字符串连接到该字符串的末尾。 如果参数字符串的长度为0 ,则返回此String对象。
         * 这里使用了new String(buf, true)
         *  否则,返回一个String对象,表示一个字符序列,该字符序列是由该String对象表示的字符序列与由参数字符串表示的字符序列的级联。 
         *  如果需要大量的字符串拼接,请使用StringBuffer和StringBuilder
         */
        public String concat(String str) {
            int otherLen = str.length();
            if (otherLen == 0) {
                return this;
            }
            int len = value.length;
            char buf[] = Arrays.copyOf(value, len + otherLen);
            str.getChars(buf, len);
            return new String(buf, true);
        }
    
        /*
         * 判断此字符串是否匹配指定的regaex正则表达式,正则表达式有些复杂,需要一章来叙述,这里不做赘述
         */
        public boolean matches(String regex) {
            return Pattern.matches(regex, this);
        }
    
        /*
         * 判断此字符串是否包含指定的字符序列CharSequence,CharSequence在上面已经讲过了
         */
        public boolean contains(CharSequence s) {
            return indexOf(s.toString()) > -1;
        }
        /*
         * 替换字符串中的某个字符,注意参数都是字符char类型
         * 例如:"gollong".replace("o","")的结果为"gllng"
         */
        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;
                    }
                }
                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++;
                    }
                    return new String(buf, true);
                }
            }
            return this;
        }
    
    
        /*
         * 替换字符串中的字字符串,识别方式为正则表达式
         * replaceFirst只替换第一个
         * replaceAll为全部替换
         */
        public String replaceFirst(String regex, String replacement) {
            return Pattern.compile(regex).matcher(this).replaceFirst(replacement);
        }
        public String replaceAll(String regex, String replacement) {
            return Pattern.compile(regex).matcher(this).replaceAll(replacement);
        }
        public String replace(CharSequence target, CharSequence replacement) {
            return Pattern.compile(target.toString(), Pattern.LITERAL).matcher(this)
                    .replaceAll(Matcher.quoteReplacement(replacement.toString()));
        }
    
        /*
         * 切割字符串,形参regex是一个正则表达式。limit用于限制String[]的长度
         * 例如,字符串"boo:and:foo"使用以下参数产生以下结果: 
         * Regex Limit         Result 
         * :       2       { "boo", "and:foo" } 
         * :       5       { "boo", "and", "foo" } 
         * :       -2      { "boo", "and", "foo" } 
         * o       5       { "b", "", ":and:f", "", "" } 
         * o       -2      { "b", "", ":and:f", "", "" } 
         * o       0       { "b", "", ":and:f" } 
    
         */
        public String[] split(String regex, int limit) {
            char ch = 0;
            if (((regex.value.length == 1 && ".$|()[{^?*+\".indexOf(ch = regex.charAt(0)) == -1)
                    || (regex.length() == 2 && regex.charAt(0) == '\' && (((ch = regex.charAt(1)) - '0') | ('9' - ch)) < 0
                            && ((ch - 'a') | ('z' - ch)) < 0 && ((ch - 'A') | ('Z' - ch)) < 0))
                    && (ch < Character.MIN_HIGH_SURROGATE || ch > Character.MAX_LOW_SURROGATE)) {
                int off = 0;
                int next = 0;
                boolean limited = limit > 0;
                ArrayList<String> list = new ArrayList<>();
                while ((next = indexOf(ch, off)) != -1) {
                    if (!limited || list.size() < limit - 1) {
                        list.add(substring(off, next));
                        off = next + 1;
                    } else { // last one
                        // assert (list.size() == limit - 1);
                        list.add(substring(off, value.length));
                        off = value.length;
                        break;
                    }
                }
                // If no match was found, return this
                if (off == 0)
                    return new String[] { this };
    
                // Add remaining segment
                if (!limited || list.size() < limit)
                    list.add(substring(off, value.length));
    
                // Construct result
                int resultSize = list.size();
                if (limit == 0) {
                    while (resultSize > 0 && list.get(resultSize - 1).length() == 0) {
                        resultSize--;
                    }
                }
                String[] result = new String[resultSize];
                return list.subList(0, resultSize).toArray(result);
            }
            return Pattern.compile(regex).split(this, limit);
        }
        
        public String[] split(String regex) {
            return split(regex, 0);
        }
    
        /*
         * 去掉字符串两端的空格,很有用的小方法
         */
        public String trim() {
            int len = value.length;
            int st = 0;
            char[] val = value; /* avoid getfield opcode */
    
            while ((st < len) && (val[st] <= ' ')) {
                st++;
            }
            while ((st < len) && (val[len - 1] <= ' ')) {
                len--;
            }
            return ((st > 0) || (len < value.length)) ? substring(st, len) : this;
        }
    
        /*
         * toString返回这个对象本身,
         * 重点:我们总以为直接输出一个字符串对象可以打印其char数组的内容是因为String重写了toString方法
         *     我们认为System.out.println(str)就是System.out.println(str.toString())
         *     其实不是的,我们很清楚的看到了,toString方法就是返回一个String对象,并不是遍历
         *     于是乎我们得到了一个结论:
         *         System.out.println(str.toString())就是System.out.println(str)他们都依赖于String的特殊的实现机制
         *         这个机制就是:String s = "gollopng"就是创造对象并实例化
         *                  System.out.println(str)就是直接遍历输出
         */
        public String toString() {
            return this;
        }
    
        /*
         * 将字符串转换为char数组,此时联想一下charAt方法,不要记混了
         */
        public char[] toCharArray() {
            // Cannot use Arrays.copyOf because of class initialization order issues
            char result[] = new char[value.length];
            System.arraycopy(value, 0, result, 0, value.length);
            return result;
        }
        
        /*
         * 返回字符串对象的规范表示,它遵循以下规则:对于任意两个字符串 s 和 t,当且仅当 s.equals(t) 为 true 时,s.intern() == t.intern() 才为 true。
         * 尽管在输出中调用intern方法并没有什么效果,但是实际上后台这个方法会做一系列的动作和操作。在调用”gollong”.intern()方法的时候会返回”gollong”,
         * 但是这个方法会首先检查字符串常量池中是否有”gollong”这个字符串,如果存在则该引用指向它,否则就将这个字符添加到字符串池中,然会再指向。
         */
        public native String intern();
        
        
        /*
         * 返回一个新的字符串,由 CharSequence elements的副本组成,并附有指定的delimiter的 delimiter 
         */
        public static String join(CharSequence delimiter, CharSequence... elements) {
            Objects.requireNonNull(delimiter);
            Objects.requireNonNull(elements);
            // Number of elements not likely worth Arrays.stream overhead.
            StringJoiner joiner = new StringJoiner(delimiter);
            for (CharSequence cs : elements) {
                joiner.add(cs);
            }
            return joiner.toString();
        }
    
        /*
         * 返回一个新 String的副本组成 CharSequence elements与指定的副本一起加入 delimiter 。
         */
        public static String join(CharSequence delimiter, Iterable<? extends CharSequence> elements) {
            Objects.requireNonNull(delimiter);
            Objects.requireNonNull(elements);
            StringJoiner joiner = new StringJoiner(delimiter);
            for (CharSequence cs : elements) {
                joiner.add(cs);
            }
            return joiner.toString();
        }
    
        /*
         * toLowerCase(Locale locale):将字符串中所有小写字符转换为大写,其中locale用于指定自己的规则
         * toUpperCase(Locale locale):将字符串中所有大写字符转换为小写,其中locale用于指定自己的规则
         */
        public String toLowerCase(Locale locale) {
            if (locale == null) {
                throw new NullPointerException();
            }
    
            int firstUpper;
            final int len = value.length;
    
            /* Now check if there are any characters that need to be changed. */
            scan: {
                for (firstUpper = 0; firstUpper < len;) {
                    char c = value[firstUpper];
                    if ((c >= Character.MIN_HIGH_SURROGATE) && (c <= Character.MAX_HIGH_SURROGATE)) {
                        int supplChar = codePointAt(firstUpper);
                        if (supplChar != Character.toLowerCase(supplChar)) {
                            break scan;
                        }
                        firstUpper += Character.charCount(supplChar);
                    } else {
                        if (c != Character.toLowerCase(c)) {
                            break scan;
                        }
                        firstUpper++;
                    }
                }
                return this;
            }
    
            char[] result = new char[len];
            int resultOffset = 0; 
            System.arraycopy(value, 0, result, 0, firstUpper);
    
            String lang = locale.getLanguage();
            boolean localeDependent = (lang == "tr" || lang == "az" || lang == "lt");
            char[] lowerCharArray;
            int lowerChar;
            int srcChar;
            int srcCount;
            for (int i = firstUpper; i < len; i += srcCount) {
                srcChar = (int) value[i];
                if ((char) srcChar >= Character.MIN_HIGH_SURROGATE && (char) srcChar <= Character.MAX_HIGH_SURROGATE) {
                    srcChar = codePointAt(i);
                    srcCount = Character.charCount(srcChar);
                } else {
                    srcCount = 1;
                }
                if (localeDependent || srcChar == 'u03A3' || // GREEK CAPITAL LETTER SIGMA
                        srcChar == 'u0130') { // LATIN CAPITAL LETTER I WITH DOT ABOVE
                    lowerChar = ConditionalSpecialCasing.toLowerCaseEx(this, i, locale);
                } else {
                    lowerChar = Character.toLowerCase(srcChar);
                }
                if ((lowerChar == Character.ERROR) || (lowerChar >= Character.MIN_SUPPLEMENTARY_CODE_POINT)) {
                    if (lowerChar == Character.ERROR) {
                        lowerCharArray = ConditionalSpecialCasing.toLowerCaseCharArray(this, i, locale);
                    } else if (srcCount == 2) {
                        resultOffset += Character.toChars(lowerChar, result, i + resultOffset) - srcCount;
                        continue;
                    } else {
                        lowerCharArray = Character.toChars(lowerChar);
                    }
    
                    /* Grow result if needed */
                    int mapLen = lowerCharArray.length;
                    if (mapLen > srcCount) {
                        char[] result2 = new char[result.length + mapLen - srcCount];
                        System.arraycopy(result, 0, result2, 0, i + resultOffset);
                        result = result2;
                    }
                    for (int x = 0; x < mapLen; ++x) {
                        result[i + resultOffset + x] = lowerCharArray[x];
                    }
                    resultOffset += (mapLen - srcCount);
                } else {
                    result[i + resultOffset] = (char) lowerChar;
                }
            }
            return new String(result, 0, len + resultOffset);
        }
        public String toLowerCase() {
            return toLowerCase(Locale.getDefault());
        }
        public String toUpperCase(Locale locale) {
            if (locale == null) {
                throw new NullPointerException();
            }
            int firstLower;
            final int len = value.length;
            scan: {
                for (firstLower = 0; firstLower < len;) {
                    int c = (int) value[firstLower];
                    int srcCount;
                    if ((c >= Character.MIN_HIGH_SURROGATE) && (c <= Character.MAX_HIGH_SURROGATE)) {
                        c = codePointAt(firstLower);
                        srcCount = Character.charCount(c);
                    } else {
                        srcCount = 1;
                    }
                    int upperCaseChar = Character.toUpperCaseEx(c);
                    if ((upperCaseChar == Character.ERROR) || (c != upperCaseChar)) {
                        break scan;
                    }
                    firstLower += srcCount;
                }
                return this;
            }
            int resultOffset = 0;
            char[] result = new char[len]; 
            System.arraycopy(value, 0, result, 0, firstLower);
    
            String lang = locale.getLanguage();
            boolean localeDependent = (lang == "tr" || lang == "az" || lang == "lt");
            char[] upperCharArray;
            int upperChar;
            int srcChar;
            int srcCount;
            for (int i = firstLower; i < len; i += srcCount) {
                srcChar = (int) value[i];
                if ((char) srcChar >= Character.MIN_HIGH_SURROGATE && (char) srcChar <= Character.MAX_HIGH_SURROGATE) {
                    srcChar = codePointAt(i);
                    srcCount = Character.charCount(srcChar);
                } else {
                    srcCount = 1;
                }
                if (localeDependent) {
                    upperChar = ConditionalSpecialCasing.toUpperCaseEx(this, i, locale);
                } else {
                    upperChar = Character.toUpperCaseEx(srcChar);
                }
                if ((upperChar == Character.ERROR) || (upperChar >= Character.MIN_SUPPLEMENTARY_CODE_POINT)) {
                    if (upperChar == Character.ERROR) {
                        if (localeDependent) {
                            upperCharArray = ConditionalSpecialCasing.toUpperCaseCharArray(this, i, locale);
                        } else {
                            upperCharArray = Character.toUpperCaseCharArray(srcChar);
                        }
                    } else if (srcCount == 2) {
                        resultOffset += Character.toChars(upperChar, result, i + resultOffset) - srcCount;
                        continue;
                    } else {
                        upperCharArray = Character.toChars(upperChar);
                    }
                    int mapLen = upperCharArray.length;
                    if (mapLen > srcCount) {
                        char[] result2 = new char[result.length + mapLen - srcCount];
                        System.arraycopy(result, 0, result2, 0, i + resultOffset);
                        result = result2;
                    }
                    for (int x = 0; x < mapLen; ++x) {
                        result[i + resultOffset + x] = upperCharArray[x];
                    }
                    resultOffset += (mapLen - srcCount);
                } else {
                    result[i + resultOffset] = (char) upperChar;
                }
            }
            return new String(result, 0, len + resultOffset);
        }
    
        public String toUpperCase() {
            return toUpperCase(Locale.getDefault());
        }
    
        /*
         * 使用指定的格式字符串和参数返回格式化的字符串。 Object... args是可变参数
         */
        public static String format(String format, Object... args) {
            return new Formatter().format(format, args).toString();
        }
    
        /*
         * 使用指定的区域设置,格式字符串和参数返回格式化的字符串。 
         */
        public static String format(Locale l, String format, Object... args) {
            return new Formatter(l).format(format, args).toString();
        }
    
        /*
         * 下面是String通过静态方法将其他类型转换为字符串
         * 总结:将其他类型转换为字符串有三种方法
         *     1.String的构造器:可以转换byte[]、char[]、int[]
         *     2.String的静态方法valueOf:可以转换Object对象、char[]、boolean、char、int、long、float、double
         *     3.其他类型的toString方法:只要是重写了toString,就可以转换
         */
        public static String valueOf(Object obj) {
            return (obj == null) ? "null" : obj.toString();
        }
        public static String valueOf(char data[]) {
            return new String(data);
        }
        public static String valueOf(char data[], int offset, int count) {
            return new String(data, offset, count);
        }
    
        public static String copyValueOf(char data[], int offset, int count) {
            return new String(data, offset, count);
        }
    
        public static String copyValueOf(char data[]) {
            return new String(data);
        }
    
        public static String valueOf(boolean b) {
            return b ? "true" : "false";
        }
        public static String valueOf(char c) {
            char data[] = { c };
            return new String(data, true);
        }
        public static String valueOf(int i) {
            return Integer.toString(i);
        }
        public static String valueOf(long l) {
            return Long.toString(l);
        }
        public static String valueOf(float f) {
            return Float.toString(f);
        }
        public static String valueOf(double d) {
            return Double.toString(d);
        }
    
        
  • 相关阅读:
    Reverse Integer
    Reverse Bits
    Number of 1 Bits
    House Robber
    02-线性结构1. 一元多项式求导 (25)
    01-复杂度2. Maximum Subsequence Sum (25)
    <转载>使CSS文字图片div元素居中方法之水平居中的几个方法
    <转载>div+css布局教程之div+css常见布局结构定义
    15个必须知道的chrome开发者技巧
    <转载>Div+Css布局教程(-)CSS必备知识
  • 原文地址:https://www.cnblogs.com/gollong/p/9366046.html
Copyright © 2011-2022 走看看