11. String基础知识

String:内部用final的char数组实现,是一个final类,也就是说不能被继承,所以他一旦被实例化就无法被修改。

String需要特别注意的有:

  1. replaceFirst、replaceAll、replace区别

  2. String 对"+" 的重载

  3. String.valueOf和Integer.toString的区别

1.replaceFirst、replaceAll、replace区别

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()));
    }

 对比这三个方法的源码可得,String.replaceFirstString.replaceAll用的是同一种正则规则compile(String regex)初始化,而replace用的是compile(String regex,int flags)替换方法String.replaceAllString.replace都是用的Martcher.replaceAll(String) ,而String.replaceFirst用的是Martcher.replaceFirst(String)方法

/**
     * Compiles the given regular expression into a pattern with the given
     * flags.
     *     使用给定的标志将给定的正则表达式编译为模式。
     * @param  regex
     *         The expression to be compiled
     *
     * @param  flags
     *         Match flags, a bit mask that may include

     *         标志如下:
     *         {@link #CASE_INSENSITIVE}, {@link #MULTILINE}, {@link #DOTALL},
     *         {@link #UNICODE_CASE}, {@link #CANON_EQ}, {@link #UNIX_LINES},
     *         {@link #LITERAL}, {@link #UNICODE_CHARACTER_CLASS}
     *         and {@link #COMMENTS}
     *
     * @return the given regular expression compiled into a pattern with the given flags
     */
    public static Pattern compile(String regex, int flags) {
        return new Pattern(regex, flags);
    }

 String.replace()使用的是Pattern.LITERAL。

   /**
     * Enables literal parsing of the pattern.
     *
     * <p> When this flag is specified then the input string that specifies
     * the pattern is treated as a sequence of literal characters.
     * Metacharacters or escape sequences in the input sequence will be
     * given no special meaning.
     *
     * <p>The flags CASE_INSENSITIVE and UNICODE_CASE retain their impact on
     * matching when used in conjunction with this flag. The other flags
     * become superfluous.
     *
     * <p> There is no embedded flag character for enabling literal parsing.
     * @since 1.5
     */
    public static final int LITERAL = 0x10;

 由注释可得,输入序列中的元字符或转义序列将没有特殊含义。即String.replace正则表达式不起作用,被强转为普通的字符串。

 而String.replaceFirst和String.replaceAll使用的是常规Pattern构造函数,所以正则表达式是会起作用

 接下来再看看Matcher.replaceAll,Matcher.replaceFirst源码

public String replaceAll(String replacement) {
        reset();
        boolean result = find();
        if (result) {
            StringBuffer sb = new StringBuffer();
            do {
                appendReplacement(sb, replacement);
                result = find();
            } while (result);
            appendTail(sb);
            return sb.toString();
        }
        return text.toString();
    }

public String replaceFirst(String replacement) {
        if (replacement == null)
            throw new NullPointerException("replacement");
        reset();
        if (!find())
            return text.toString();
        StringBuffer sb = new StringBuffer();
        appendReplacement(sb, replacement);
        appendTail(sb);
        return sb.toString();
    }

 明显,Matcher.replaceAll使用do-while循环替换匹配的字符串,而Matcher.replaceFirst只做了一次匹配替换。即String.replaceAll和String.replace将会替换字符串中所有能匹配上的字符串,而String.replaceFirst只会替换第一次匹配上的字符串。

 2.String 对"+" 的重载

文章开头说过,String是一个final类,用final char[]实现,所以一旦赋值,String将不可变。所以String类中每一个修改String的方法其实都是生成了新的String对象。

String a = "create " + "a ";    //①

String string = a + "final " + "String!";     //②

①在编译期就会直接编译成String a = "create a ";

②在编译期会编译成new StringBuilder().append("create a ").append("final ").append("String").toString();

String result = "";

for(int i = 0; i < strArray.length; i++)

result += strArray[i];   //当strArraylist很大时,很产生很多的StringBuilder对象,因为每一个循环都会创建一个。

 

StringBuilder result1 = new StringBuilder();

for(int i = 0; i < strArray.length; i++)

result1.append(strArray[i]);    //正确用法
 

3.String.valueOf和Integer.toString的区别

String.valueOf()方法可以将各种类型转换成String,内部实现了多种类型的String的处理方式。

    public static String valueOf(boolean b) {
        return b ? "true" : "false";
    }

    public static String valueOf(Object obj) {
        return (obj == null) ? "null" : obj.toString();
    }

    public static String valueOf(char c) {
        char data[] = {c};
        return new String(data, true);
    }

    public static String valueOf(int i) {
        return Integer.toString(i);
    }

    ......

 由源码得String.valueOf(int)内部其实是调用了Integer.toString();

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值