Guava 原生类型 工具类
一、介绍
Java中存在八中基本类型 byte
、short
、int
、long
、float
、double
、char
和 boolean
,基本类型不能当作对象或泛型的类型参数使用,这意味着许多通用方法都不能应用于它们。
Guava提供了若干通用工具,包括基本类型数组与集合API的交互,基本类型和字节数组的相互转换,以及对某些基本类型的无符号形式的支持。
Guava工具类都在 com.google.common.primitives
包
基本类型 | Guava工具类 |
---|---|
byte | Bytes , SignedBytes, UnsignedBytes |
short | Shorts |
int | Ints , UnsignedInteger, UnsignedInts |
long | Longs , UnsignedLong, UnsignedLongs |
char | Chars |
float | Floats |
double | Doubles |
boolean | Booleans |
Bytes
工具类没有定义任何区分有符号和无符号字节的方法,而是把它们都放到了 SignedBytes
和 UnsignedBytes
工具类中,因为字节类型的符号性比起其它类型要略微含糊一些。
int
和 long
的无符号形式方法在 UnsignedInts
和 UnsignedLongs
类中,但由于这两个类型的大多数用法都是有符号的,Ints
和 Longs
类按照有符号形式处理方法的输入参数。
此外,Guava为 int
和 long
的无符号形式提供了包装类,即 UnsignedInteger
和 UnsignedLong
,以帮助你使用类型系统,以极小的性能消耗对有符号和无符号值进行强制转换。
二、无符号整数和有符号整数怎么区分?
有无符号的整数,在计算机内存中是区别不出有无符号的,而是在程序里有区分。
计算机里的数是用二进制表示的,最左边的这一位一般用来表示这个数是正数还是负数,这样的话这个数就是有符号整数。
如果最左边这一位不用来表示正负,而是和后面的连在一起表示整数,那么就不能区分这个数是正还是负,就只能是正数,这就是无符号整数。
计算机中的整数分为两类:
不带符号位的整数(unsigned integer,也称为无符号整数),此类整数一定是正整数;
带符号位的整数(signed integer),此类整数可以表示正整数,又可以表示负整数。
有符号和无符号的差别:
int 是有符号的。
unsigned 是无符号的。
它们所占的字节数其实是一样的,但是有符号的需要安排一个位置来表达我这个数值的符号,因此说它能表示的绝对值就要比无符号的少一半。
举个例子,我们有一个1个 [1]
字节的整数(虽然这种类型不存在),那么无符号的就是这样:00000000~11111111
这个就是无符号的范围。
一个字节是8位,有符号的数,因为第一个位要用来表示符号,那么就只剩下7个位置可以用来表示数了 0000000~1111111
因为有符号,所以还可以表示范围:-1111111 ~ +1111111
。
三、原生类型数组工具
在下面描述的方法签名中,用 Wrapper
表示JDK包装类,prim
表示原生类型。(Prims表示相应的Guava工具类)
原生类型数组是处理原生类型集合的最有效方式(从内存和性能双方面考虑),Guava为此提供了许多工具方法。
方法签名 | 描述 | 类似方法 | 可用性 |
---|---|---|---|
List<Wrapper> asList(prim… backingArray) | 把数组转为相应包装类的List | Arrays.asList | 符号无关 |
prim[] toArray(Collection<Wrapper>collection) | 把集合拷贝为数组,和 collection.toArray() 一样线程安全 | Collection.toArray() | 符号无关 |
prim[] concat(prim[]… arrays) | 串联多个原生类型数组 | Iterables.concat | 符号无关 |
boolean contains(prim[] array, prim target) | 判断原生类型数组是否包含给定值 | Collection.contains | 符号无关 |
int indexOf(prim[] array, prim target) | 给定值在数组中首次出现处的索引,若不包含此值返回-1 | List.indexOf | 符号无关 |
int lastIndexOf(prim[] array, prim target) | 给定值在数组最后出现的索引,若不包含此值返回-1 | List.lastIndexOf | 符号无关 |
prim min(prim… array) | 数组中最小的值 | Collections.min | 符号相关 |
prim max(prim… array) | 数组中最大的值 | Collections.max | 符号相关 |
String join(String separator, prim… array) | 把数组用给定分隔符连接为字符串 | Joiner.on(separator).join | 符号相关 |
Comparator<prim[]>lexicographicalComparator() | 按字典序比较原生类型数组的Comparator | Ordering.natural().lexicographical() | 符号相关 |
符号无关方法存在于:Bytes
, Shorts
, Ints
, Longs
, Floats
, Doubles
, Chars
, Booleans
。而 UnsignedInts
, UnsignedLongs
, SignedBytes
或 UnsignedBytes
不存在。
符号相关方法存在于:SignedBytes
, UnsignedBytes
, Shorts
, Ints
, Longs
, Floats
, Doubles
, Chars
, Booleans
, UnsignedInts
, UnsignedLongs
。而 Bytes
不存在。
四、通用工具方法
Guava 为原生类型提供了若干 JDK6 没有的工具方法。但请注意,其中某些方法已经存在于 JDK7 中。
方法签名 | 描述 | 可用性 |
---|---|---|
int compare(prim a, prim b) | 传统的Comparator.compare方法,但针对原生类型。JDK7的原生类型包装类也提供这样的方法 | 符号相关 |
prim checkedCast(long value) | 把给定long值转为某一原生类型,若给定值不符合该原生类型,则抛出IllegalArgumentException | 仅适用于符号相关的整型 |
prim saturatedCast(long value) | 把给定long值转为某一原生类型,若给定值不符合则使用最接近的原生类型值 | 仅适用于符号相关的整型 |
这里的整型包括:byte
, short
, int
, long
。不包括:char
, boolean
, float
, 或 double
。
注意: 不符合主要是指long值超出prim类型的范围,比如过大的long超出int范围。
字节转换方法
Guava提供了若干方法,用来把原生类型按大字节序与字节数组相互转换。所有这些方法都是符号无关的,此外 Booleans 没有提供任何下面的方法。
方法或字段签名 | 描述 |
---|---|
int BYTES | 常量:表示该原生类型需要的字节数 |
prim fromByteArray(byte[] bytes) | 使用字节数组的前 Prims.BYTES 个字节,按大字节序返回原生类型值;如果 bytes.length <= Prims.BYTES,抛出IAE |
prim fromBytes(byte b1, …, byte bk) | 接受 Prims.BYTES 个字节参数,按大字节序返回原生类型值 |
byte[] toByteArray(prim value) | 按大字节序返回value的字节数组 |
五、无符号支持
JDK原生类型包装类提供了针对有符号类型的方法,而 UnsignedInts
和 UnsignedLongs
工具类提供了相应的无符号通用方法。UnsignedInts
和 UnsignedLongs
直接处理原生类型:使用时,由你自己保证只传入了无符号类型的值。
此外,对 int
和 long
,Guava提供了无符号包装类(UnsignedInteger
和 UnsignedLong
),来帮助你以极小的性能消耗,对有符号和无符号类型进行强制转换。
无符号通用工具方法
JDK的原生类型包装类提供了有符号形式的类似方法。
方法签名 | 说明 |
---|---|
int UnsignedInts.parseUnsignedInt(String) long UnsignedLongs.parseUnsignedLong(String) | 按无符号十进制解析字符串 |
int UnsignedInts.parseUnsignedInt(String string, int radix) long UnsignedLongs.parseUnsignedLong(String string, int radix) | 按无符号的特定进制解析字符串 |
String UnsignedInts.toString(int) String UnsignedLongs.toString(long) | 数字按无符号十进制转为字符串 |
String UnsignedInts.toString(int value, int radix) String UnsignedLongs.toString(long value, int radix) | 数字按无符号特定进制转为字符串 |
无符号包装类
无符号包装类包含了若干方法,让使用和转换更容易。
方法签名 | 说明 |
---|---|
UnsignedPrim add(UnsignedPrim) , subtract, multiply, divide, remainder | 简单算术运算 |
UnsignedPrim valueOf(BigInteger) | 按给定BigInteger返回无符号对象,若BigInteger为负或不匹配,抛出IAE |
UnsignedPrim valueOf(long) | 按给定long返回无符号对象,若long为负或不匹配,抛出IAE |
UnsignedPrim asUnsigned(prim value) | 把给定的值当作无符号类型。例如,UnsignedInteger.asUnsigned(1<<31)的值为231,尽管1<<31当作int时是负的 |
BigInteger bigIntegerValue() | 用BigInteger返回该无符号对象的值 |
toString() toString(int radix) | 返回无符号值的字符串表示 |
译者注:UnsignedPrim
指各种无符号包装类,如 UnsignedInteger
、UnsignedLong
。
六、相关文章
未经允许请勿转载:程序喵 » Google Guava 快速入门 —— 原生类型工具类