Guava学习笔记(2)Strings

2018-05-20  本文已影响0人  懵逼猴

从Guava.Strings的提供的一些方法开始学习

padStart和padEnd方法

padStart(String string, int minLength, char padChar)
padEnd(String string, int minLength, char padChar)

padStart 返回一个字符串,其长度至少为minLength,如果长度小于minLength,则在字符串的前面添加若干个padChar,直到长度为minLength;如果长度大于minLength则直接返回字符串。padEnd则是长度不够的时候在字符串末尾添加padChar。

repeat方法

public static String repeat(String string, int count) {
    // 首先判断输入的参数是否合法
    checkNotNull(string); 
    if (count <= 1) {
      checkArgument(count >= 0, "invalid count: %s", count);
      return (count == 0) ? "" : string;
    }

    // IF YOU MODIFY THE CODE HERE, you must update StringsRepeatBenchmark
    final int len = string.length();
    final long longSize = (long) len * (long) count;
    final int size = (int) longSize;
   // 如果字符长度超出int范围则抛出错误
    if (size != longSize) {
      throw new ArrayIndexOutOfBoundsException("Required array size too large: " + longSize);
    }

    final char[] array = new char[size];
    // 将字符串中的字符复制到目标字符数组中,实际也调用了System.arraycopy这个本地方法
    string.getChars(0, len, array, 0);
    int n;
   // 这里使用到了移位运算,使得每次复制的数据都是上一次的2倍,总的循环的次数变为log(count)次,提高了效率
    for (n = len; n < size - n; n <<= 1) {
      System.arraycopy(array, 0, array, n, n);
    }
    // 如果count为奇数,则还要进行依次额外的复制操作
    System.arraycopy(array, 0, array, n, size - n);
    return new String(array);
  }

下面来看一下System.arraycopy这个方法的功能。首先看一下方法的声明

arraycopy(Object src,  int  srcPos,Object dest, int destPos, int length)

其功能是将源数组中从指定位置开始的数据复制到目标数组的指定位置之后的数据中去,复制数据的长度为length。也就是将源数组中指定位置srcPos到srcPos + length-1中的数据复制到 destPos到 destPos + length-1地方去。

    // 惯例,先判断参数的合法性
    checkNotNull(a);
    checkNotNull(b);
    int maxPrefixLength = Math.min(a.length(), b.length());
    int p = 0;
    while (p < maxPrefixLength && a.charAt(p) == b.charAt(p)) {
      p++;
    }
    if (validSurrogatePairAt(a, p - 1) || validSurrogatePairAt(b, p - 1)) {
      p--;
    }
    return a.subSequence(0, p).toString();

说明:众所周知java采用UTF-16编码unicode字符集。UTF-16使用使用一个16位单元(两字节)或者两个16为单元表示一个unicode字符。使用两个单元的,前面那个单元叫highsurrogate 后面那个叫lowsurrogate。而char只占一个16位单元(两字节),在判断的时候使用的char来进行的比较。所以最后一个字符是占4字节的字符的时候会出现highsurrogate 相同,lowsurrogate不同,非同一个单元对,这就表明不是一个相同的字符。所以公共前缀的长度需要减一。

static boolean validSurrogatePairAt(CharSequence string, int index) {
    return index >= 0
        && index <= (string.length() - 2)
        && Character.isHighSurrogate(string.charAt(index))
        && Character.isLowSurrogate(string.charAt(index + 1));
  }

参考链接如下:

Java中char占用几个字节
StringBuffer.reverse()中surrogate pair的问题
String和CharSequence的区别

上一篇 下一篇

猜你喜欢

热点阅读