前言
今天来看看
Long
这个类的源码。
Long相关概念
Long是被final修饰的,因此该类不能被继承。另外它是long类的包装类。继承了抽象类Number,并且实现了Comparable接口,所以可以进行参数的比较。
Long 源码
package java.lang;
import jdk.internal.HotSpotIntrinsicCandidate;
import java.lang.annotation.Native;
import java.math.BigInteger;
import java.util.Objects;
import static java.lang.String.COMPACT_STRINGS;
import static java.lang.String.LATIN1;
import static java.lang.String.UTF16;
//Long是被final修饰的,因此该类不能被继承。另外它是long类的包装类。继承了抽象类Number,并且实现了Comparable接口,所以可以进行参数的比较。
public final class Long extends Number implements Comparable<Long> {
/** use serialVersionUID from JDK 1.0.2 for interoperability */
@Native
private static final long serialVersionUID = 4290774380558885855L;
// 相当于long.class
@SuppressWarnings("unchecked")
public static final Class<Long> TYPE = (Class<Long>) Class.getPrimitiveClass("long");
/**
* long最小值 -2^63
*/
@Native
public static final long MIN_VALUE = 0x8000000000000000L;
/**
* have, 2<sup>63</sup>-1.
* long最大值 (2^63)-1
*/
@Native
public static final long MAX_VALUE = 0x7fffffffffffffffL;
/**
*当前类型所占bit[位]数(Long类型占用8个字节,也就是64位)
* @since 1.5
*/
@Native
public static final int SIZE = 64;
/**
*当前类型所占字节数(Long类型占8个字节)
* 8 = 64 / 8
* @since 1.8
*/
public static final int BYTES = SIZE / Byte.SIZE;
// 当前类包装的值
private final long value;
// Long有参构造,传入long类型参数,用于创建Long对象
@Deprecated(since = "9")
public Long(long value) {
this.value = value;
}
/**
* Long有参构造,传入String类型参数,用于创建Long对象
*/
@Deprecated(since = "9")
public Long(String s) throws NumberFormatException {
this.value = parseLong(s, 10);
}
/**
* long类型转换为Long 类型.(装箱)
* @since 1.5
*/
@HotSpotIntrinsicCandidate
public static Long valueOf(long l) {
final int offset = 128;
// 如果 -128 <= l <=127 直接从缓存中取出该对象,否则直接实例化
if(l >= -128 && l<=127) {
return LongCache.cache[(int) l + offset];
}
return new Long(l);
}
// 按10进制形式将字符串s解析为long值,随后再装箱
public static Long valueOf(String s) throws NumberFormatException {
return Long.valueOf(parseLong(s, 10));// 第二个参数表示10进制
}
// 按radix进制形式将字符串s解析为long值,随后再装箱
public static Long valueOf(String s, int radix) throws NumberFormatException {
return Long.valueOf(parseLong(s, radix));
}
/*
* 将字符串nm解析为long,随后再装箱
*
* 采用哪种进制解析nm取决于nm的格式:
* > 0x、0X、#开头,代表按16进制解析
* > 0开头,代表按8进制解析
* > 其他情形默认按10进制解析
*/
public static Long decode(String nm) throws NumberFormatException {
int radix = 10;
int index = 0;
boolean negative = false;
Long result;
if(nm.length() == 0)
throw new NumberFormatException("Zero length string");
char firstChar = nm.charAt(0);
// Handle sign, if present
if(firstChar == '-') {
negative = true;
index++;
} else if(firstChar == '+')
index++;
// 判断该字符串位X进制格式
if(nm.startsWith("0x", index) || nm.startsWith("0X", index)) {
index += 2;
radix = 16;
} else if(nm.startsWith("#", index)) {
index++;
radix = 16;
} else if(nm.startsWith("0", index) && nm.length()>1 + index) {
index++;
radix = 8;
}
if(nm.startsWith("-", index) || nm.startsWith("+", index))
throw new NumberFormatException("Sign character in wrong position");
try {
result = Long.valueOf(nm.substring(index), radix);
result = negative ? Long.valueOf(-result.longValue()) : result;
} catch(NumberFormatException e) {
String constant = negative ? ("-" + nm.substring(index)) : nm.substring(index);
result = Long.valueOf(constant, radix);
}
return result;
}
/**
* 重写父类(Number)方法,将Long值转换为byte类型
*/
public byte byteValue() {
return (byte) value;
}
/**
* 重写父类(Number)方法,将Long值转换为short类型
*/
public short shortValue() {
return (short) value;
}
/**
* 重写父类(Number)方法,将Long值转换为int类型
*/
public int intValue() {
return (int) value;
}
/**
* 重写父类(Number)方法,将Long值转换为long类型:拆箱
*/
@HotSpotIntrinsicCandidate
public long longValue() {
return value;
}
/**
* 重写父类(Number)方法,将Long值转换为float类型
*/
public float floatValue() {
return (float) value;
}
/**
*重写父类(Number)方法,将Long值转换为double类型
*/
public double doubleValue() {
return (double) value;
}
/*
* 从系统属性中获取值,然后再装箱
* 其中,nm为某个系统属性,val为备用值
*
* 比如:
* System.setProperty("age", "20");
* Long x = getLong("age", 25);
* 如果属性age存在(被提前设置),x的值为20。
* 如果属性age不存在,则x的值为备用值25。
*/
public static Long getLong(String nm, Long val) {
String v = null;
try {
v = System.getProperty(nm);
} catch(IllegalArgumentException | NullPointerException e) {
}
if(v != null) {
try {
return Long.decode(v);
} catch(NumberFormatException e) {
}
}
return val;
}
// 从系统属性中获取值,然后再装箱。如果取不到值,选用val
public static Long getLong(String nm, long val) {
Long result = Long.getLong(nm, null);
return (result == null) ? Long.valueOf(val) : result;
}
// 从系统属性中获取值,然后再装箱。如果取不到值,返回null
public static Long getLong(String nm) {
return getLong(nm, null);
}
/**
* 按radix进制形式将字符串s解析为long值
* parseLong("0", 10) returns 0L
* parseLong("473", 10) returns 473L
* parseLong("+42", 10) returns 42L
* parseLong("-0", 10) returns 0L
* parseLong("-FF", 16) returns -255L
* parseLong("1100110", 2) returns 102L
* parseLong("99", 8) throws a NumberFormatException
* parseLong("Hazelnut", 10) throws a NumberFormatException
* parseLong("Hazelnut", 36) returns 1356099454469L
*/
public static long parseLong(String s, int radix) throws NumberFormatException {
if(s == null) {
throw new NumberFormatException("null");
}
if(radix<Character.MIN_RADIX) { // 进制转换约束下限,最小2进制
throw new NumberFormatException("radix " + radix + " less than Character.MIN_RADIX");
}
if(radix>Character.MAX_RADIX) {// 进制转换约束上限,最大36进制,因为10个数字+26个字母的限制
throw new NumberFormatException("radix " + radix + " greater than Character.MAX_RADIX");
}
boolean negative = false;
int i = 0, len = s.length();
long limit = -Long.MAX_VALUE;
if(len>0) {
char firstChar = s.charAt(0);
if(firstChar<'0') { // Possible leading "+" or "-"
if(firstChar == '-') {
negative = true;
limit = Long.MIN_VALUE;
} else if(firstChar != '+') {
throw NumberFormatException.forInputString(s);
}
if(len == 1) { // Cannot have lone "+" or "-"
throw NumberFormatException.forInputString(s);
}
i++;
}
long multmin = limit / radix;
long result = 0;
while(i<len) {
// Accumulating negatively avoids surprises near MAX_VALUE
int digit = Character.digit(s.charAt(i++), radix);
if(digit<0 || result<multmin) {
throw NumberFormatException.forInputString(s);
}
result *= radix;
if(result<limit + digit) {
throw NumberFormatException.forInputString(s);
}
result -= digit;
}
return negative ? result : -result;
} else {
throw NumberFormatException.forInputString(s);
}
}
// 按10进制形式将字符串s解析为long值
public static long parseLong(String s) throws NumberFormatException {
return parseLong(s, 10);
}
/**
* 按radix进制形式将字符序列s的[beginIndex, endIndex)部分解析为long值
* @since 9
*/
public static long parseLong(CharSequence s, int beginIndex, int endIndex, int radix) throws NumberFormatException {
s = Objects.requireNonNull(s);
if(beginIndex<0 || beginIndex>endIndex || endIndex>s.length()) {
throw new IndexOutOfBoundsException();
}
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");
}
boolean negative = false;
int i = beginIndex;
long limit = -Long.MAX_VALUE;
if(i<endIndex) {
char firstChar = s.charAt(i);
if(firstChar<'0') { // Possible leading "+" or "-"
if(firstChar == '-') {
negative = true;
limit = Long.MIN_VALUE;
} else if(firstChar != '+') {
throw NumberFormatException.forCharSequence(s, beginIndex, endIndex, i);
}
i++;
}
if(i >= endIndex) { // Cannot have lone "+", "-" or ""
throw NumberFormatException.forCharSequence(s, beginIndex, endIndex, i);
}
long multmin = limit / radix;
long result = 0;
while(i<endIndex) {
// Accumulating negatively avoids surprises near MAX_VALUE
int digit = Character.digit(s.charAt(i), radix);
if(digit<0 || result<multmin) {
throw NumberFormatException.forCharSequence(s, beginIndex, endIndex, i);
}
result *= radix;
if(result<limit + digit) {
throw NumberFormatException.forCharSequence(s, beginIndex, endIndex, i);
}
i++;
result -= digit;
}
return negative ? result : -result;
} else {
throw new NumberFormatException("");
}
}
/**
* 按radix进制形式将无符号整型字符串s解析为有符号整型值
* @since 1.8
*/
public static long parseUnsignedLong(String s, int radix) throws NumberFormatException {
if(s == null) {
throw new NumberFormatException("null");
}
int len = s.length();
if(len>0) {
char firstChar = s.charAt(0);
if(firstChar == '-') {
throw new NumberFormatException(String.format("Illegal leading minus sign " + "on unsigned string %s.", s));
} else {
if(len<=12 || // Long.MAX_VALUE in Character.MAX_RADIX is 13 digits
(radix == 10 && len<=18)) { // Long.MAX_VALUE in base 10 is 19 digits
return parseLong(s, radix);
}
// No need for range checks on len due to testing above.
long first = parseLong(s, 0, len - 1, radix);
int second = Character.digit(s.charAt(len - 1), radix);
if(second<0) {
throw new NumberFormatException("Bad digit at end of " + s);
}
long result = first * radix + second;
int guard = radix * (int) (first >>> 57);
if(guard >= 128 || (result >= 0 && guard >= 128 - Character.MAX_RADIX)) {
throw new NumberFormatException(String.format("String value %s exceeds " + "range of unsigned long.", s));
}
return result;
}
} else {
throw NumberFormatException.forInputString(s);
}
}
// 按10进制形式将无符号整型字符串s解析为有符号整型值
public static long parseUnsignedLong(String s) throws NumberFormatException {
return parseUnsignedLong(s, 10);
}
/*
* 按radix进制形式将无符号整型字符序列s的[beginIndex, endIndex)部分解析为有符号整型值
* @since 9
*/
public static long parseUnsignedLong(CharSequence s, int beginIndex, int endIndex, int radix) throws NumberFormatException {
s = Objects.requireNonNull(s);
if(beginIndex<0 || beginIndex>endIndex || endIndex>s.length()) {
throw new IndexOutOfBoundsException();
}
int start = beginIndex, len = endIndex - beginIndex;
if(len>0) {
char firstChar = s.charAt(start);
if(firstChar == '-') {
throw new NumberFormatException(String.format("Illegal leading minus sign " + "on unsigned string %s.", s.subSequence(start, start + len)));
} else {
if(len<=12 || // Long.MAX_VALUE in Character.MAX_RADIX is 13 digits
(radix == 10 && len<=18)) { // Long.MAX_VALUE in base 10 is 19 digits
return parseLong(s, start, start + len, radix);
}
// No need for range checks on end due to testing above.
long first = parseLong(s, start, start + len - 1, radix);
int second = Character.digit(s.charAt(start + len - 1), radix);
if(second<0) {
throw new NumberFormatException("Bad digit at end of " + s.subSequence(start, start + len));
}
long result = first * radix + second;
/*
* Test leftmost bits of multiprecision extension of first*radix
* for overflow. The number of bits needed is defined by
* GUARD_BIT = ceil(log2(Character.MAX_RADIX)) + 1 = 7. Then
* int guard = radix*(int)(first >>> (64 - GUARD_BIT)) and
* overflow is tested by splitting guard in the ranges
* guard < 92, 92 <= guard < 128, and 128 <= guard, where
* 92 = 128 - Character.MAX_RADIX. Note that guard cannot take
* on a value which does not include a prime factor in the legal
* radix range.
*/
int guard = radix * (int) (first >>> 57);
if(guard >= 128 || (result >= 0 && guard >= 128 - Character.MAX_RADIX)) {
/*
* For purposes of exposition, the programmatic statements
* below should be taken to be multi-precision, i.e., not
* subject to overflow.
*
* A) Condition guard >= 128:
* If guard >= 128 then first*radix >= 2^7 * 2^57 = 2^64
* hence always overflow.
*
* B) Condition guard < 92:
* Define left7 = first >>> 57.
* Given first = (left7 * 2^57) + (first & (2^57 - 1)) then
* result <= (radix*left7)*2^57 + radix*(2^57 - 1) + second.
* Thus if radix*left7 < 92, radix <= 36, and second < 36,
* then result < 92*2^57 + 36*(2^57 - 1) + 36 = 2^64 hence
* never overflow.
*
* C) Condition 92 <= guard < 128:
* first*radix + second >= radix*left7*2^57 + second
* so that first*radix + second >= 92*2^57 + 0 > 2^63
*
* D) Condition guard < 128:
* radix*first <= (radix*left7) * 2^57 + radix*(2^57 - 1)
* so
* radix*first + second <= (radix*left7) * 2^57 + radix*(2^57 - 1) + 36
* thus
* radix*first + second < 128 * 2^57 + 36*2^57 - radix + 36
* whence
* radix*first + second < 2^64 + 2^6*2^57 = 2^64 + 2^63
*
* E) Conditions C, D, and result >= 0:
* C and D combined imply the mathematical result
* 2^63 < first*radix + second < 2^64 + 2^63. The lower
* bound is therefore negative as a signed long, but the
* upper bound is too small to overflow again after the
* signed long overflows to positive above 2^64 - 1. Hence
* result >= 0 implies overflow given C and D.
*/
throw new NumberFormatException(String.format("String value %s exceeds " + "range of unsigned long.", s.subSequence(start, start + len)));
}
return result;
}
} else {
throw NumberFormatException.forInputString("");
}
}
// 按10进制返回当前long的值
public String toString() {
return toString(value);
}
// 按10进制返回i的值
public static String toString(long i) {
int size = stringSize(i);
if(COMPACT_STRINGS) {
byte[] buf = new byte[size];
getChars(i, size, buf);
return new String(buf, LATIN1);
} else {
byte[] buf = new byte[size * 2];
StringUTF16.getChars(i, size, buf);
return new String(buf, UTF16);
}
}
// 按radix进制返回i的值
public static String toString(long i, int radix) {
// 进制转换约束下限,最小2进制.进制转换约束上限,最大36进制,因为10个数字+26个字母的限制
if(radix<Character.MIN_RADIX || radix>Character.MAX_RADIX) {
// 默认为10进制
radix = 10;
}
if(radix == 10) {
return toString(i);
}
if(COMPACT_STRINGS) {
byte[] buf = new byte[65];
int charPos = 64;
boolean negative = (i<0);
if(!negative) {
i = -i;
}
while(i<=-radix) {
buf[charPos--] = (byte) Integer.digits[(int) (-(i % radix))];
i = i / radix;
}
buf[charPos] = (byte) Integer.digits[(int) (-i)];
if(negative) {
buf[--charPos] = '-';
}
return StringLatin1.newString(buf, charPos, (65 - charPos));
}
return toStringUTF16(i, radix);
}
/**
* 按2进制返回i的无符号值
* @since 1.0.2
*/
public static String toBinaryString(long i) {
return toUnsignedString0(i, 1);// 2^1 = 2进制
}
/**
* 按8进制返回i的无符号值
* @since 1.0.2
*/
public static String toOctalString(long i) {
return toUnsignedString0(i, 3);// 2^3 = 2进制
}
/**
* 按10进制返回i的无符号值
* @since 1.8
*/
public static String toUnsignedString(long i) {
return toUnsignedString(i, 10);
}
/**
* 按16进制返回i的无符号值
* @since 1.0.2
*/
public static String toHexString(long i) {
return toUnsignedString0(i, 4);// 2^4 = 16进制
}
/**
* 按radix进制返回i的无符号值
* @since 1.8
*/
public static String toUnsignedString(long i, int radix) {
if(i >= 0) {
return toString(i, radix);
}
switch(radix) {
case 2:
return toBinaryString(i);
case 4:
return toUnsignedString0(i, 2);
case 8:
return toOctalString(i);
case 10:
long quot = (i >>> 1) / 5;
long rem = i - quot * 10;
return toString(quot) + rem;
case 16:
return toHexString(i);
case 32:
return toUnsignedString0(i, 5);
default:
return toUnsignedBigInteger(i).toString(radix);
}
}
/**
* 按2^shift进制返回val的无符号值
*/
static String toUnsignedString0(long val, int shift) {
// assert shift > 0 && shift <=5 : "Illegal shift value";
int mag = Long.SIZE - Long.numberOfLeadingZeros(val);
int chars = Math.max(((mag + (shift - 1)) / shift), 1);
if(COMPACT_STRINGS) {
byte[] buf = new byte[chars];
formatUnsignedLong0(val, shift, buf, 0, chars);
return new String(buf, LATIN1);
} else {
byte[] buf = new byte[chars * 2];
formatUnsignedLong0UTF16(val, shift, buf, 0, chars);
return new String(buf, UTF16);
}
}
// 按radix进制返回i的无符号值,UTF16版本
private static String toStringUTF16(long i, int radix) {
byte[] buf = new byte[65 * 2];
int charPos = 64;
boolean negative = (i<0);
if(!negative) {
i = -i;
}
while(i<=-radix) {
StringUTF16.putChar(buf, charPos--, Integer.digits[(int) (-(i % radix))]);
i = i / radix;
}
StringUTF16.putChar(buf, charPos, Integer.digits[(int) (-i)]);
if(negative) {
StringUTF16.putChar(buf, --charPos, '-');
}
return StringUTF16.newString(buf, charPos, (65 - charPos));
}
// 将数字0到9分别存储为对应的ANSI码,'\0'存储为数字0。byte[]/LATIN1版本。参见Integer#formatUnsignedInt
static void formatUnsignedLong0(long val, int shift, byte[] buf, int offset, int len) {
int charPos = offset + len;
int radix = 1 << shift;
int mask = radix - 1;
do {
buf[--charPos] = (byte) Integer.digits[((int) val) & mask];
val >>>= shift;
} while(charPos>offset);
}
// 将数字0到9分别存储为对应的ANSI码,'\0'存储为数字0。byte[]/UTF16版本。参见Integer#formatUnsignedInt
private static void formatUnsignedLong0UTF16(long val, int shift, byte[] buf, int offset, int len) {
int charPos = offset + len;
int radix = 1 << shift;
int mask = radix - 1;
do {
StringUTF16.putChar(buf, --charPos, Integer.digits[((int) val) & mask]);
val >>>= shift;
} while(charPos>offset);
}
/**
* 统计整数i中包含的符号数量(包括负号),为转为字符串做准备
* 比如stringSize(12345)返回5,stringSize(-12345)返回6
*/
static int stringSize(long x) {
int d = 1;
if(x >= 0) {
d = 0; // 如果是正数 d=0
x = -x; // 如果是正数 x变为-x 在下面 x>p做准备
}// 如果是负数,d=1,那么就可以把负号也统计进来
long p = -10;
for(int i = 1; i<19; i++) {//这里之所以循环19次,是因为long的最大值9_223_372_036_854_775_807为19位
if(x>p)// 此时x永远为负数,p也是负数且每次扩大一位,所以当满足x>p的时候,返回i+d即可得到符号数量
return i + d;
p = 10 * p;// 每次*10,表示增加一位
}
return 19 + d;// 只有当x处于19位长度才满足该条件
}
/**
* 将整数i中包含的符号转为byte存入buf
*/
static int getChars(long i, int index, byte[] buf) {
long q;
int r;
int charPos = index;
boolean negative = (i<0);
if(!negative) {
i = -i;
}
// Get 2 digits/iteration using longs until quotient fits into an int
while(i<=Integer.MIN_VALUE) {
q = i / 100;
r = (int) ((q * 100) - i);
i = q;
buf[--charPos] = Integer.DigitOnes[r];
buf[--charPos] = Integer.DigitTens[r];
}
// Get 2 digits/iteration using ints
int q2;
int i2 = (int) i;
while(i2<=-100) {
q2 = i2 / 100;
r = (q2 * 100) - i2;
i2 = q2;
buf[--charPos] = Integer.DigitOnes[r];
buf[--charPos] = Integer.DigitTens[r];
}
// We know there are at most two digits left at this point.
q2 = i2 / 10;
r = (q2 * 10) - i2;
buf[--charPos] = (byte) ('0' + r);
// Whatever left is the remaining digit.
if(q2<0) {
buf[--charPos] = (byte) ('0' - q2);
}
if(negative) {
buf[--charPos] = (byte) '-';
}
return charPos;
}
/**
* 将当前long转换为无符号形式,用BigInteger存储
*/
private static BigInteger toUnsignedBigInteger(long i) {
if(i >= 0L)
return BigInteger.valueOf(i);
else {
int upper = (int) (i >>> 32);
int lower = (int) i;
// return (upper << 32) + lower
return (BigInteger.valueOf(Integer.toUnsignedLong(upper))).shiftLeft(32).
add(BigInteger.valueOf(Integer.toUnsignedLong(lower)));
}
}
/**
*比较两个long类型值的大小(按自然顺序比较)
* @since 1.7
*/
public static int compare(long x, long y) {
return (x<y) ? -1 : ((x == y) ? 0 : 1);
}
/**
* 比较两个Long(按自然顺序比较)
* @since 1.2
*/
public int compareTo(Long anotherLong) {
return compare(this.value, anotherLong.value);
}
/**
*以无符号形式比较两个long(按自然顺序比较)
* @since 1.8
*/
public static int compareUnsigned(long x, long y) {
// 在这里对x、y都和Long的最小值相加。
// 所以如果x、y是负数,那么和最小值相加后就会导致数据溢出,从而结果会在 MIN_VALUE <= n <= MAX_VALUE 范围区间内形成闭环
return compare(x + MIN_VALUE, y + MIN_VALUE);
}
/**
*返回long类型转化为二进制之后1的个数
* @since 1.5
*/
@HotSpotIntrinsicCandidate
public static int bitCount(long i) {
//1.求出i对应的二进制数的每两位之和,比如(01)(11)(10)(00)-->(01)(10)(01)(00)
i = i - ((i >>> 1) & 0x5555555555555555L);
//2.求出(1.)中i对应的二进制数的每四位之和,比如(0110)(0001)(1001)(1001) -->(0010)(0001)(0010)(0010)
i = (i & 0x3333333333333333L) + ((i >>> 2) & 0x3333333333333333L);
//3.同上求出(2.)中i的二进制数的每八位之和。
i = (i + (i >>> 4)) & 0x0f0f0f0f0f0f0f0fL;
//4.同上求出(3.)中i的二进制数的每十六位之和。
i = i + (i >>> 8);
//5.同上求出(4.)中i的二进制数的每三十二位之和
i = i + (i >>> 16);
//6.同上求出(5.)中i的二进制数的每六十四位之和。
i = i + (i >>> 32);
//1的个数最多也不会超过64个,所以只取最后7位即可。
return (int) i & 0x7f;
}
/**
* 循环左移,也就是将i向左移动distance位,
* 当i的移位到达了最高位还没有够distance,那么移位的数就去低位开头,继续移位。
* 所以叫做循环移位。distance可以为负
* @since 1.5
*/
public static long rotateLeft(long i, int distance) {
// <<表示左移移,不分正负数,低位补0;
// >>>表示无符号右移,也叫逻辑右移,即若该数为正,则高位补0,而若该数为负数,则右移后高位同样补0
// | 表示 按位或。只要对应的二个二进位有一个为1时,结果位就为1。当参与运算的是负数时,参与两个数均以补码出现。
// 补充:如果i为负数,那么需要对给该值进行反码,补码后再去移位
// i =1 distance=2
// i << distance) 表示 1 左移两位
// i >>> -distance) 表示 1 无符号右移 ?位
return (i << distance) | (i >>> -distance);
}
/**
* 循环右移,也就是将i向右移动distance位,
* 当i的移位到达了最低位还没有够distance,那么移位的数就去高位开头,继续移位。
* 所以叫做循环移位。distance可以为负
* @since 1.5
*/
public static long rotateRight(long i, int distance) {
return (i >>> distance) | (i << -distance);
}
/**
* 把i转化为二进制数,然后再把这个二进制数反转,
* 参考文章:https://blog.youkuaiyun.com/songylwq/article/details/9015581
* @since 1.5
*/
public static long reverse(long i) {
// HD, Figure 7-1
i = (i & 0x5555555555555555L) << 1 | (i >>> 1) & 0x5555555555555555L;
i = (i & 0x3333333333333333L) << 2 | (i >>> 2) & 0x3333333333333333L;
i = (i & 0x0f0f0f0f0f0f0f0fL) << 4 | (i >>> 4) & 0x0f0f0f0f0f0f0f0fL;
return reverseBytes(i);
}
/**
* 判断i的正负。遇到负数返回-1,正数返回1,0返回0。
*
* 如果i是正数,那么i >> 63肯定为0,-i为负数,-i >>> 63无符号右移,肯定为1,所以结果为1。
* 当i为0的时候结果为0,这个就不在分析。当i为负数的时候,i >> 63结果为……1111(共64个1)
* ,-i >>> 63无论结果是什么,最终结果都是……1111(64个1),他是-1的补码,所以结果为-1。
*
* 而为什么移位数是63?是因为Long类型占用8个字节,64位,移位63位后首位就是符号位了
* @since 1.5
*/
public static int signum(long i) {
return (int) ((i >> 63) | (-i >>> 63));
}
/**
*以字节为单位逆置字节顺序
* @since 1.5
*/
@HotSpotIntrinsicCandidate
public static long reverseBytes(long i) {
i = (i & 0x00ff00ff00ff00ffL) << 8 | (i >>> 8) & 0x00ff00ff00ff00ffL;
return (i << 48) | ((i & 0xffff0000L) << 16) | ((i >>> 16) & 0xffff0000L) | (i >>> 48);
}
/**
* 返回二进制位中开头连续的0的个数(把int值i表示为二进制形式)
* @since 1.5
*/
@HotSpotIntrinsicCandidate
public static int numberOfLeadingZeros(long i) {
int x = (int) (i >>> 32);// long为64位,无符号右移32(Integer为32位)位后.
// 由于高位补0,即补32个零,为了调用下面的Integer的方法做准备
// 如果此时x==0 ,则返回 32 + 32 = 64,否则调用Integer.numberOfLeadingZeros(x)返回具体的个数
return x == 0 ? 32 + Integer.numberOfLeadingZeros((int) i) : Integer.numberOfLeadingZeros(x);
}
/**
* 返回二进制位中末尾连续的0的个数(把int值i表示为二进制形式)
* 基于二分查找
* @since 1.5
*/
@HotSpotIntrinsicCandidate
public static int numberOfTrailingZeros(long i) {
// HD, Figure 5-14
int x, y;
if(i == 0)
return 64;// long为64位
int n = 63;
y = (int) i;
if(y != 0) {
n = n - 32;
x = y;
} else
x = (int) (i >>> 32);
y = x << 16;
if(y != 0) {
n = n - 16;
x = y;
}
y = x << 8;
if(y != 0) {
n = n - 8;
x = y;
}
y = x << 4;
if(y != 0) {
n = n - 4;
x = y;
}
y = x << 2;
if(y != 0) {
n = n - 2;
x = y;
}
return n - ((x << 1) >>> 31);
}
/**
* 该方法返回i的二进制中最高位的1,其他全为0的值。
* 比如i=10时,二进制即为1010,最高位的1,其他为0,则是1000。
* 比如i=2时,二进制即为0010,最高位的1,其他为0,则是0010。
* 比如i=3时,二进制即为0011,最高位的1,其他为0,则是0010 :2
* 如果i=0,则返回0。
* 如果i为负数则固定返回Long.MIN_VALUE,因为负数的最高位一定是1,即有1000,0000,0000,0000,0000,0000,0000,0000。
* 参考:https://www.jb51.net/article/127763.htm
* @since 1.5
*/
public static long highestOneBit(long i) {
return i & (MIN_VALUE >>> numberOfLeadingZeros(i));
}
/**
* 该方法返回i的二进制中最低位1,其他全为0的值。
* 这个操作较简单,先取负数,这个过程需要对正数的i取反码然后再加1,得到的结果和i进行与操作,刚好就是最低位1其他为0的值了。
* 比如i=2时,二进制即为000...0010,-2的取反补码后1111 ... 1110, 000...0010 & 1111 ... 1110 = 000...0010 = 2
* 比如i=3时,二进制即为000...0011,-3的取反补码后1111 ... 1101, 000...0011 & 1111 ... 1101 = 000...0001 = 1
* 比如i=10时,二进制即为000...1010,-10的取反补码后1111 ... 0110, 000...1010 & 1111 ... 0110 = 000...0010 = 2
* 参考:https://www.jb51.net/article/127763.htm
* @since 1.5
*/
public static long lowestOneBit(long i) {
// & 表示 按位与 只有对应的两个二进位都为1时,结果位才为1。参与运算的两个数均以补码出现。
return i & -i;
}
/**
*返回 a + b 的值
* @since 1.8
*/
public static long sum(long a, long b) {
return a + b;
}
/**
* 调用Math.max(a, b)方法,返回两数中最大的一个
* @since 1.8
*/
public static long max(long a, long b) {
return Math.max(a, b);
}
/**
* 调用Math.min(a, b)方法,返回两数中最大的一个
* @since 1.8
*/
public static long min(long a, long b) {
return Math.min(a, b);
}
/**
* 除法运算。计算前需要先将两个long值转换为无符号形式
* @param dividend 被除数
* @param divisor 除数
* @since 1.8
*/
public static long divideUnsigned(long dividend, long divisor) {
if(divisor<0L) { // signed comparison
// Answer must be 0 or 1 depending on relative magnitude of dividend and divisor.
return (compareUnsigned(dividend, divisor))<0 ? 0L : 1L;
}
if(dividend>0) {
// 被除数和除数都大于0
return dividend / divisor;
} else {
/*
* For simple code, leveraging BigInteger.
* Longer and faster code written directly in terms of operations on longs is possible;
* see "Hacker's Delight" for divide and remainder algorithms.
*/
return toUnsignedBigInteger(dividend).divide(toUnsignedBigInteger(divisor)).longValue();
}
}
/**
* 取余运算。计算前需要先将两个long值转换为无符号形式
* @since 1.8
*/
public static long remainderUnsigned(long dividend, long divisor) {
if(dividend>0 && divisor>0) { // signed comparisons
return dividend % divisor;
} else {
if(compareUnsigned(dividend, divisor)<0) { // Avoid explicit check for 0 divisor
return dividend;
} else {
return toUnsignedBigInteger(dividend).remainder(toUnsignedBigInteger(divisor)).longValue();
}
}
}
/**
*返回 Long 的哈希码
* @since 1.8
*/
public static int hashCode(long value) {
// 首先将long型值无符号右移32位,再和原来的值进行异或运算,最后返回int类型值。
// 异或运算规则:(参考:https://www.cnblogs.com/tmdsleep/p/9933647.html)
// 0^0 = 0
// 1^0 = 1
// 0^1 = 1
// 1^1 = 0
return (int) (value ^ (value >>> 32));
}
/**
* 将Long类型转换为long类型.然后用==比较值是否相等。
* 如果不是obj不是Long类型,则直接返回不相等
*/
public boolean equals(Object obj) {
if(obj instanceof Long) {
return value == ((Long) obj).longValue();
}
return false;
}
// Long缓存区间,缓存了-128~127之间的Long对象
private static class LongCache {
// 创建256个Long对象数组,用来缓存-128~127之间的对象
static final Long cache[] = new Long[-(-128) + 127 + 1];
static {
for(int i = 0; i<cache.length; i++)
cache[i] = new Long(i - 128);
}
private LongCache() {
}
}
Long源码测试
1.取值范围测试
@Test
public void test(){
Long max = 9223372036854775807L;
// Long max = 9223372036854775808L; // 超出范围 编译报错
Long min = -9223372036854775808L;
// Long min = -9223372036854775809L; //超出范围 编译报错
System.out.println("Long的最大值:" + Long.MAX_VALUE);// (2^63)-1 = 9223372036854775807
System.out.println("Long的最小值:" + Long.MIN_VALUE);// -(2^63) = -9223372036854775808
System.out.println("Long所占用的位数:" + Long.SIZE);// 64
System.out.println("Long所占用的字节数:" + Long.BYTES);// 8
}
2. public static Long decode(String nm)方法测试
@Test
public void testdecode(){
// 说明:计算机输出的结果默认为10进制
// 将十进制1 转为long,在装箱转为Long
System.out.println(Long.decode("1"));// 结果:1
// 将八进制031 转为long,在装箱转为Long
System.out.println(Long.decode("031"));//结果:25
// 将十六进制0xf 转为long,在装箱转为Long
System.out.println(Long.decode("0xf"));// 结果:15
// 将十进制21474836488 转为int,在转为int
System.out.println(Long.decode("9223372036854775808L"));// 结果:java.lang.NumberFormatException: For input string: "9223372036854775808L" (9223372036854775808L超出了long取值范围)
}
3. public static Long getLong(String nm, Long val)方法测试
@Test
public void testgetLong(){
// 从系统属性中获取值,如果获取不到则使用默认值。然后再装箱
System.out.println(Long.getLong("age",10L));// 结果:10L
// 从系统属性中获取值,然后再装箱.,如果取不到,则返回null
System.out.println(Long.getLong("age"));// 结果:10L
// 先向系统赋值,在获取
System.setProperty("no","1");
System.out.println(Long.getLong("no"));// 结果:1
}
4. public static String toString(long i)方法测试
@Test
public void testtoString(){
System.out.println(Long.toString(4));// 4
System.out.println(Long.toString(-4));// -4
// 以2进制形式输出4
System.out.println(Long.toString(4,2));// 100
// 以2进制形式输出-4
System.out.println(Long.toString(-4,2));// -100
// 以4进制形式输出4
System.out.println(Long.toString(4,4));// 10
// 以4进制形式输出-4
System.out.println(Long.toString(-4,4));// -10
}
5. static int stringSize(long x)方法测试
@Test
public void teststringSize(){
//统计整数i中包含的符号数量(包括负号),为转为字符串做准备
long x = Long.MAX_VALUE;
System.out.println(stringSize(x));// 19
System.out.println(stringSize(-123l));// 4
}
static int stringSize(long x) {
int d = 1;
if(x >= 0) {
d = 0;
x = -x;
}
long p = -10;
for(int i = 1; i<19; i++) {//这里之所以循环19次,是因为long的最大值9_223_372_036_854_775_807为19位
if(x>p)
return i + d;
p = 10 * p;
}
return 19 + d;// 只有当x处于19位长度才满足该条件
}
6. public static int compare(int x, int y)方法测试
@Test
public void testcompare(){
// 比较两个int(按自然顺序比较)
// (x < y) ? -1 : ((x == y) ? 0 : 1);
System.out.println(Long.compare(-5,3));// -1
System.out.println(Long.compare(3,3));// 0
System.out.println(Long.compare(5,3));// 1
}
7.public static int compareUnsigned(long x, long y)方法测试
@Test
public void testcompareUnsigned(){
// 以无符号形式比较两个int(按自然顺序比较)
// 在这里对x、y都和Long的最小值相加。
// 所以如果x、y是负数,那么和最小值相加后就会导致数据溢出,从而结果会在 MIN_VALUE <= n <= MAX_VALUE 范围区间内形成闭环
// return compare(x + MIN_VALUE, y + MIN_VALUE);
System.out.println(Long.compareUnsigned(-1,3));// -1 + Long.MIN_VALUE=9223372036854775807 所以结果为1
System.out.println(Long.compareUnsigned(-5,-3));// -5 + Long.MIN_VALUE=9223372036854775803,-3 + Long.MIN_VALUE=9223372036854775805 所以结果为-1
System.out.println(Long.compareUnsigned(3,3));// 0
System.out.println(Long.compareUnsigned(5,3));// 1
}
8.public static int bitCount(long i)方法测试
@Test
public void testbitCount(){
//返回int类型转化为二进制之后1的个数
System.out.println(Long.bitCount(1));// 01 ——> 1
System.out.println(Long.bitCount(2));// 10 ——> 1
System.out.println(Long.bitCount(10));// 1010 ——> 2
}
9.public static int signum(long i)方法测试
@Test
public void testsignum(){
// 判断i的正负。遇到负数返回-1,正数返回1,0返回0。
System.out.println(Long.signum(1));// 1
System.out.println(Long.signum(0));// 0
System.out.println(Long.signum(-2));// -1
}
10.public static int numberOfLeadingZeros(long i)方法测试
@Test
public void testnumberOfLeadingZeros(){
// 计算 i 的二进制从头开始有多少个连续的 0.(Long为64位)
// 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0001 = 63
System.out.println(Long.numberOfLeadingZeros(1));
// 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 = 64
System.out.println(Long.numberOfLeadingZeros(0));
// 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0010 = 62
System.out.println(Long.numberOfLeadingZeros(2));
}
11.public static int numberOfTrailingZeros(long i)方法测试
@Test
public void testnumberOfTrailingZeros(){
// 计算 i 的二进制从末尾开始有多少个连续的 0 .(Long为64位)
// 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0001 = 0
System.out.println(Long.numberOfTrailingZeros(1));
// 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 = 64
System.out.println(Long.numberOfTrailingZeros(0));
// 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0010 = 1
System.out.println(Long.numberOfTrailingZeros(2));
}
12.public static long highestOneBit(long i)方法测试
@Test
public void highestOneBit(){
// 该方法返回i的二进制中最高位的1,其他全为0的值。
// i=2时,二进制即为0000 ... 0010,最高位的1,其他为0,则是0010 : 2
System.out.println(Long.highestOneBit(2));
// i=3时,二进制即为0000 ... 0011,最高位的1,其他为0,则是0010 : 2
System.out.println(Long.highestOneBit(3));
//i=10时,二进制即为0000 ... 1010,最高位的1,其他为0,则是1000 :8
System.out.println(Long.highestOneBit(10));
// 比如i未负数时,固定返回Long.MIN_VALUE
System.out.println(Long.highestOneBit(-10));
System.out.println(Long.highestOneBit(-2));
}
13.public static long lowestOneBit(long i)方法测试
@Test
public void lowestOneBit(){
// 该方法返回i的二进制中最低位1,其他全为0的值。
// i & -i;
// 比如i=2时,二进制即为000...0010,-2的取反补码后1111 ... 1110, 000...0010 & 1111 ... 1110 = 000...0010 = 2
System.out.println(Long.lowestOneBit(2));
//比如i=3时,二进制即为000...0011,-3的取反补码后1111 ... 1101, 000...0011 & 1111 ... 1101 = 000...0001 = 1
System.out.println(Long.lowestOneBit(3));
//比如i=10时,二进制即为000...1010,-10的取反补码后1111 ... 0110, 000...1010 & 1111 ... 0110 = 000...0010 = 2
System.out.println(Long.lowestOneBit(10));
}
14.计算方法测试
@Test
public void test2(){
// 获取两数之和
System.out.println(Long.sum(-1, -20)); // -21
// 获取两个值中最大的一个
System.out.println(Long.max(-1, -20)); // -1
// 获取两个值中最小的一个
System.out.println(Long.min(-1, -20)); // -20
// 获取两个值相除的结果
System.out.println(Long.divideUnsigned(4, 2)); // 2
// 获取两个值取余的结果
System.out.println(Long.remainderUnsigned(35, 3)); // 2
}
15.public boolean equals(Object obj)方法测试
@Test
public void test3(){
// 测试值相等(要考虑缓存区间-128-127)
// 1.取值在[-128, 127]区间内,值相同,则相同,结果为true,因为使用的是同一个对象
// 2.取值在[-128, 127]区间外,即(-∞, -128) ∪(127, +∞),值相同,但对象引用不同,结果为false;
// 3.两个变量其中之一或均使用new关键字赋值时,如Long i1 = new Long(?); Long i2 = new Long(?);则都是两个不同的对象
Long a = 1L;
Long b = 1L;
System.out.println("a ==b : " + (a == b));// true
System.out.println("a.equals(b): " + (a.equals(b)));// true
Long c = 128L;
Long d = 128L;
System.out.println("c ==b : " + (c == d));// false
System.out.println("c.equals(d): " + (c.equals(d)));// true
Long e = new Long(1L);
Long f = new Long(1L);
System.out.println("e ==f : " + (e == f));// false
System.out.println("e.equals(f): " + (e.equals(f)));// true
}
重要总结:
因为Long存在缓存区间,因此在[-128,127]之间都会使用同一个对象(new Long除外),因此Long类型只能用equals()方法进行比较值相等。