备注:代码皆为源码,有些英文注释删掉了。
一、StringBuilder
如果说String是固定长度的且不能修改内容的字符串, StringBuilder就是长度可变的且能够修改内容的字符串;
都是字符数组,只不过对字符串的操作有些地方不一样。
- append,参数类型有很多,详见下方API。
@Override
public StringBuilder append(String str) {
super.append(str);
return this;
}
//父类源码
public AbstractStringBuilder append(String str) {
if (str == null)
return appendNull();
int len = str.length();
ensureCapacityInternal(count + len);
str.getChars(0, len, value, count);
count += len;
return this;
}
private AbstractStringBuilder appendNull() {
int c = count;
ensureCapacityInternal(c + 4);
final char[] value = this.value;
value[c++] = 'n';
value[c++] = 'u';
value[c++] = 'l';
value[c++] = 'l';
count = c;
return this;
}
private void ensureCapacityInternal(int minimumCapacity) {
if (minimumCapacity - value.length > 0)
expandCapacity(minimumCapacity);
}
void expandCapacity(int minimumCapacity) {
int newCapacity = value.length * 2 + 2;// 原容量*2+2 作为备选新的容量,这里有可能会
//发生溢出。
/*
*如果容量还是较小,就把minimumCapacity作为容量大小,如果溢出就会变为相应的负数,所以将
*int型最大值Integer.MAX_VALUE作为容量
*/
if (newCapacity - minimumCapacity < 0)
newCapacity = minimumCapacity;
if (newCapacity < 0) {
if (minimumCapacity < 0) // 溢出
throw new OutOfMemoryError();
newCapacity = Integer.MAX_VALUE;
}
value = Arrays.copyOf(value, newCapacity);//动态扩容(就是增大数组的容量大小)
}
在调用append方法时,向父类AbstractStringBuilder传入一个字符串数据类型,先对字符串进行判空处理,如果为空,直接return,结束该方法的调用,此处返回值appendNull调用了本类的方法其实也就是返回null;然后将字符串的length()方法求得的长度用变量len保存起来;再接着一个ensureCapacityInternal方法是为了确保数组能有放下字符串的容量,如果放不下就会调用expendCapacity方法,其实也就是扩容,该代码的具体解释放在代码里了;保证了容量大小,接着开始将指定的字符串追加到次字符序列里,利用字符串的getChars()方法:字符串要被复制的第一个字符位于索引0处,要复制的最后一个字符位于索引 len-1
处,要复制到 value子数组的字符从索引count
处(也叫偏移量)开始,并结束于索引;然后更新数组长度,返回该数组。
- delete,参数类型有很多,详见下方API。
@Override
public StringBuilder delete(int start, int end) {
super.delete(start, end);
return this;
}
//父类源码
public AbstractStringBuilder delete(int start, int end) {
if (start < 0)
throw new StringIndexOutOfBoundsException(start);
if (end > count)
end = count;
if (start > end)
throw new StringIndexOutOfBoundsException();
int len = end - start;
if (len > 0) {
System.arraycopy(value, start+len, value, start, count-end);
//移除的字符从角标start+len开始,角标count-end结束
count -= len;
}
return this;
}
StringBuilder | delete(int start, int end) 移除此序列的子字符串中的字符。 |
StringBuilder | deleteCharAt(int index) 移除此序列指定位置上的 char 。 |
- insert(),参数类型有很多,详见下方API。
@Override
public StringBuilder insert(int dstOffset, CharSequence s,
int start, int end)
{
super.insert(dstOffset, s, start, end);
return this;
}
//父类源码
public AbstractStringBuilder insert(int dstOffset, CharSequence s,
int start, int end) {
if (s == null)
s = "null";
if ((dstOffset < 0) || (dstOffset > this.length()))
throw new IndexOutOfBoundsException("dstOffset "+dstOffset);
if ((start < 0) || (end < 0) || (start > end) || (end > s.length()))
throw new IndexOutOfBoundsException(
"start " + start + ", end " + end + ", s.length() "
+ s.length());
int len = end - start;
ensureCapacityInternal(count + len);
System.arraycopy(value, dstOffset, value, dstOffset + len,
count - dstOffset);
for (int i=start; i<end; i++)//将s的子序列插入value序列中。
value[dstOffset++] = s.charAt(i);
count += len;
return this;
}
- replace(int start, int end, String str)
使用给定 String 中的字符替换此序列的子字符串中的字符。 |
@Override
public StringBuilder replace(int start, int end, String str) {
super.replace(start, end, str);
return this;
}
//父类源码
public AbstractStringBuilder replace(int start, int end, String str) {
if (start < 0)
throw new StringIndexOutOfBoundsException(start);
if (start > count)
throw new StringIndexOutOfBoundsException("start > length()");
if (start > end)
throw new StringIndexOutOfBoundsException("start > end");
if (end > count)
end = count;
int len = str.length();
int newCount = count + len - (end - start);
ensureCapacityInternal(newCount);
//从指定源数组中复制一个数组,复制从指定的位置开始,到目标数组的指定位置结束。从value引用
//的源数组到value引用的目标数组,数组组件的一个子序列被复制下来。被复制的组件的编号等于
//count -end参数。源数组中位置在end到end+count-end-1之间的组件被分别复制到目标数组中的
//start+len到start+len+count-end-1位置。
System.arraycopy(value, end, value, start + len, count - end);
str.getChars(value, start);
count = newCount;
return this;
}
- reverse()
将此字符序列用其反转形式取代 |
与普通的反转不同不是“123”-----》“321”。而是例如,反转 "\uDC00\uD800" 将生成 "\uD800\uDC00"。
@Override
public StringBuilder reverse() {
super.reverse();
return this;
}
//父类源码
public AbstractStringBuilder reverse() {
boolean hasSurrogates = false;
int n = count - 1;
for (int j = (n-1) >> 1; j >= 0; j--) {
int k = n - j;
char cj = value[j];
char ck = value[k];
value[j] = ck;
value[k] = cj;
if (Character.isSurrogate(cj) ||
Character.isSurrogate(ck)) {
hasSurrogates = true;
}
}
if (hasSurrogates) {
reverseAllValidSurrogatePairs();
}
return this;
}
StringBuilder | append(boolean b) 将 boolean 参数的字符串表示形式追加到序列。 |
StringBuilder | append(char c) 将 char 参数的字符串表示形式追加到此序列。 |
StringBuilder | append(char[] str) 将 char 数组参数的字符串表示形式追加到此序列。 |
StringBuilder | append(char[] str, int offset, int len) 将 char 数组参数的子数组的字符串表示形式追加到此序列。 |
StringBuilder | append(CharSequence s) 向此 Appendable 追加到指定的字符序列。 |
StringBuilder | append(CharSequence s, int start, int end) 将指定 CharSequence 的子序列追加到此序列。 |
StringBuilder | append(double d) 将 double 参数的字符串表示形式追加到此序列。 |
StringBuilder | append(float f) 将 float 参数的字符串表示形式追加到此序列。 |
StringBuilder | append(int i) 将 int 参数的字符串表示形式追加到此序列。 |
StringBuilder | append(long lng) 将 long 参数的字符串表示形式追加到此序列。 |
StringBuilder | append(Object obj) 追加 Object 参数的字符串表示形式。 |
StringBuilder | append(String str) 将指定的字符串追加到此字符序列。 |
StringBuilder | append(StringBuffer sb) 将指定的 StringBuffer 追加到此序列。 |
StringBuilder | appendCodePoint(int codePoint) 将 codePoint 参数的字符串表示形式追加到此序列。 |
StringBuilder | delete(int start, int end) 移除此序列的子字符串中的字符。 |
StringBuilder | deleteCharAt(int index) 移除此序列指定位置上的 char 。 |
StringBuilder | insert(int offset, boolean b) 将 boolean 参数的字符串表示形式插入此序列中。 |
StringBuilder | insert(int offset, char c) 将 char 参数的字符串表示形式插入此序列中。 |
StringBuilder | insert(int offset, char[] str) 将 char 数组参数的字符串表示形式插入此序列中。 |
StringBuilder | insert(int index, char[] str, int offset, int len) 将数组参数 str 子数组的字符串表示形式插入此序列中。 |
StringBuilder | insert(int dstOffset, CharSequence s) 将指定 CharSequence 插入此序列中。 |
StringBuilder | insert(int dstOffset, CharSequence s, int start, int end) 将指定 CharSequence 的子序列插入此序列中。 |
StringBuilder | insert(int offset, double d) 将 double 参数的字符串表示形式插入此序列中。 |
StringBuilder | insert(int offset, float f) 将 float 参数的字符串表示形式插入此序列中。 |
StringBuilder | insert(int offset, int i) 将 int 参数的字符串表示形式插入此序列中。 |
StringBuilder | insert(int offset, long l) 将 long 参数的字符串表示形式插入此序列中。 |
StringBuilder | insert(int offset, Object obj) 将 Object 参数的字符串表示形式插入此字符序列中。 |
StringBuilder | insert(int offset, String str) 将字符串插入此字符序列中。 |
StringBuilder | replace(int start, int end, String str) 使用给定 String 中的字符替换此序列的子字符串中的字符。 |
StringBuilder | reverse() 将此字符序列用其反转形式取代。 |
二、Integer
static int | MAX_VALUE 值为 231-1 的常量,它表示 int 类型能够表示的最大值。 |
static int | MIN_VALUE 值为 -231 的常量,它表示 int 类型能够表示的最小值 |
public class NumberDemo01 {
public static void main(String[] args) {
Byte b=new Byte("10");
Short s=new Short("10");
Long l=new Long("10");
Float f=new Float("10");
Double d=new Double("10");
Character c=new Character('a');
Boolean bool=new Boolean("true");
Integer i1=new Integer(10); //10
Integer i2=new Integer("10"); //10
//成员函数
System.out.println(i1.compareTo(i2));
System.out.println(i1<i2);
System.out.println(i1+i2);
System.out.println(i1.equals(i2));
System.out.println(i1==i2);
System.out.println(i1.intValue()==i2.intValue());
System.out.println(i1.toString());//将包装类型->字符串 等效于 10+""
//静态函数
System.out.println(Integer.parseInt("123")+1); //默认以十进制解析字符串
System.out.println(Integer.parseInt("10010101",2));//以二进制解析字符串
System.out.println(Integer.parseInt("102201012",3));//以三进制解析字符串
//最高支持几进制?radix ∈ [2,36] 10个数字+26个字母
System.out.println(Integer.reverse(123));//不是我们简单认为的123-321
System.out.println(Integer.toBinaryString(149));//以二进制形式返回
System.out.println(Integer.toOctalString(149));//八进制
System.out.println(Integer.toHexString(149));//十六进制
System.out.println(Integer.toString(149));//字符串
//静态工厂模式
System.out.println(Integer.valueOf(10));//等效于 new Integer(10)
}
}
public static int parseInt(String s, int radix)
throws NumberFormatException
{
/*
* WARNING: This method may be invoked early during VM initialization
* before IntegerCache is initialized. Care must be taken to not use
* the valueOf method.
*/
if (s == null) {
throw new NumberFormatException("null");
}
if (radix < Character.MIN_RADIX) {
throw new NumberFormatException("radix " + radix +
" less than Character.MIN_RADIX");
}
if (radix > Character.MAX_RADIX) {
throw new NumberFormatException("radix " + radix +
" greater than Character.MAX_RADIX");
}
int result = 0;
boolean negative = false;
int i = 0, len = s.length();
int limit = -Integer.MAX_VALUE;
int multmin;
int digit;
if (len > 0) {
char firstChar = s.charAt(0);
if (firstChar < '0') { // Possible leading "+" or "-"
if (firstChar == '-') {
negative = true;
limit = Integer.MIN_VALUE;
} else if (firstChar != '+')
throw NumberFormatException.forInputString(s);
if (len == 1) // Cannot have lone "+" or "-"
throw NumberFormatException.forInputString(s);
i++;
}
multmin = limit / radix;
while (i < len) {
// Accumulating negatively avoids surprises near MAX_VALUE
digit = Character.digit(s.charAt(i++),radix);
if (digit < 0) {
throw NumberFormatException.forInputString(s);
}
if (result < multmin) {
throw NumberFormatException.forInputString(s);
}
result *= radix;
if (result < limit + digit) {
throw NumberFormatException.forInputString(s);
}
result -= digit;
}
} else {
throw NumberFormatException.forInputString(s);
}
return negative ? result : -result;
}
toBinaryString(int i)
public static String toBinaryString(int i) {
return toUnsignedString0(i, 1);
}
private static String toUnsignedString0(int val, int shift) {
int mag = Integer.SIZE - Integer.numberOfLeadingZeros(val);
int chars = Math.max(((mag + (shift - 1)) / shift), 1);
char[] buf = new char[chars];
formatUnsignedInt(val, shift, buf, 0, chars);
return new String(buf, true);
}
public static int numberOfLeadingZeros(int i) {
// HD, Figure 5-6
if (i == 0)
return 32;
int n = 1;
if (i >>> 16 == 0) { n += 16; i <<= 16; }
if (i >>> 24 == 0) { n += 8; i <<= 8; }
if (i >>> 28 == 0) { n += 4; i <<= 4; }
if (i >>> 30 == 0) { n += 2; i <<= 2; }
n -= i >>> 31;
return n;
}
static int formatUnsignedInt(int val, int shift, char[] buf, int offset, int len) {
int charPos = len;
int radix = 1 << shift;
int mask = radix - 1;
do {
buf[offset + --charPos] = Integer.digits[val & mask];
val >>>= shift;
} while (val != 0 && charPos > 0);
return charPos;
}
final static char[] digits = {
'0' , '1' , '2' , '3' , '4' , '5' ,
'6' , '7' , '8' , '9' , 'a' , 'b' ,
'c' , 'd' , 'e' , 'f' , 'g' , 'h' ,
'i' , 'j' , 'k' , 'l' , 'm' , 'n' ,
'o' , 'p' , 'q' , 'r' , 's' , 't' ,
'u' , 'v' , 'w' , 'x' , 'y' , 'z'
};
valueOf(int i)
public static Integer valueOf(String s, int radix) throws NumberFormatException {
return Integer.valueOf(parseInt(s,radix));
}
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}