Java8 教程

Java8 数字增强

从 Java5 开始,7 种数字原始类型的包装类 (不包含 Boolean) 都提供了一个静态字段 SIZE, 用来表示该类型以 bit 为单位的长度。例如:

System.out.println("char = " + Character.SIZE + "bit");
System.out.println("byte = " + Byte.SIZE + "bit");
System.out.println("short = " + Short.SIZE + "bit");
System.out.println("int = " + Integer.SIZE + "bit");
System.out.println("long = " + Long.SIZE + "bit");
System.out.println("float = " + Float.SIZE + "bit");
System.out.println("double = " + Double.SIZE + "bit");
//char = 16bit
//byte = 8bit
//short = 16bit
//int = 32bit
//long = 64bit
//float = 32bit
//double = 64bit

在 Java8 中,它们都提供了一个 BYTES 字段,以 byte 为单位来表示该类型的长度,以便用于无法被 8 整除的情况。例如:

System.out.println("char = " + Character.BYTES + "byte");
System.out.println("byte = " + Byte.BYTES + "byte");
System.out.println("short = " + Short.BYTES + "byte");
System.out.println("int = " + Integer.BYTES + "byte");
System.out.println("long = " + Long.BYTES + "byte");
System.out.println("float = " + Float.BYTES + "byte");
System.out.println("double = " + Double.BYTES + "byte");
//char = 2byte
//byte = 1byte
//short = 2byte
//int = 4byte
//long = 8byte
//float = 4byte
//double = 8byte

所有 8 种原始类型包装类现在都提供了一个静态的 hashCode() 方法,用来返回与实例方法相同的哈希码,这样就不再需要经历装箱/拆箱的过程了。例如:

System.out.println("char = " + Character.hashCode('A'));
System.out.println("byte = " + Byte.hashCode((byte)1));
System.out.println("short = " + Short.hashCode((short)1));
System.out.println("int = " + Integer.hashCode(1));
System.out.println("long = " + Long.hashCode(1L));
System.out.println("float = " + Float.hashCode((float)1));
System.out.println("double = " + Double.hashCode(1));
//char = 65
//byte = 1
//short = 1
//int = 1
//long = 1
//float = 1065353216
//double = 1072693248

Short、Integer、Long、Float 和 Double 这 5 种类型,现在分别提供了静态方法 sum()max() min(), 用来在流操作中作为聚合函数使用。例如:

// 以 int 为例
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);

// 求和
int sum = list.stream().reduce(Integer::sum).orElse(0);
System.out.println("sum = " + sum); // sum = 45

// 最大值
int max = list.stream().reduce(Integer::max).orElse(0);
System.out.println("max = " + max); // max = 9

// 最小值
int min = list.stream().reduce(Integer::min).orElse(0);
System.out.println("min= " + min); // min= 1

出于相同的原因,Boolean 类现在也包含了静态方法 logicalAndlogicalor logicalXor。它们定义如下:

  • static boolean logicalAnd(boolean a, boolean b)  返回对指定布尔操作数应用逻辑 AND 运算符的结果。

  • static boolean logicalOr(boolean a, boolean b)  返回对指定布尔操作数应用逻辑 OR 运算符的结果。

  • static boolean logicalXor(boolean a, boolean b)  返回对指定布尔操作数应用逻辑 XOR 运算符的结果。

例如:

boolean flag1 = true;
boolean flag2 = false;

// 使用 Boolean.logicalAnd 方法进行逻辑与操作
boolean result = Boolean.logicalAnd(flag1, flag2);
System.out.println("逻辑与的结果: " + result);
//逻辑与的结果: false

List<Boolean> booleanList = Arrays.asList(true, false, true);
boolean finalResult = booleanList.stream()
        .reduce(true, Boolean::logicalAnd);
System.out.println("列表中元素逻辑与的结果: " + finalResult);
//列表中元素逻辑与的结果: false

Integer 类现在支持无符号数学计算。例如,与以往 Byte 表示从 -128 到 127 的范围不同,你现在可以调用静态方法 Byte.toUnsignedInt(b) 来获取一个从 0 到 255 的值。一般来说,使用无符号数字,你会丢失负数并获得原来两倍范围的正数。Byte 和 Short 类中新增了 toUnsignedInt() 方法,而 Byte、Short 和 Integer 类中新增了 toUnsignedLong() 方法。例如:

byte b = (byte)0xF8;
System.out.println("b = " + b); // -8
// 1111 1000 => 248
System.out.println(Byte.toUnsignedInt(b));

Integer 和 Long 类中新增了处理无符号值的 compareUnsigned()divideUnsigned() 和 remainderUnsigned() 方法。你不需要特殊的方法来计算加法、减法和乘法。操作符 + 和 - 已经能够正确地处理无符号值。由于大于 Integer.MAX_VALUE 的无符号整数相乘会导致溢出,所以你应该调用toUnsignedLong 将它们作为长整型值相乘。例如:

int a = (int)0xFF000010;
int b = (int)0xFF000020;
// 有符号显示
System.out.println("a = " + a); // a = -16777200
System.out.println("b = " + b); // b = -16777184

// 无符号显示
System.out.println(Integer.toUnsignedLong(a)); // 4278190096
System.out.println(Integer.toUnsignedLong(b)); // 4278190112

// 比较数值
// 如果 x == y,数值为 0
// 如果 x < y,数值为小于 0 的无符号数值
// 如果 x > y,数值为大于 0 的无符号数值
// 4278190096 < 4278190112 => -1
int result = Integer.compareUnsigned(a, b); // -1
System.out.println("result= " + result);

注意:为了使用无符号数字,你需要对二进制数字及负数的二进制表示有清晰的理解。在 C 和 C++ 中,混合使用有符号类型和无符号类型容易导致一些难以察觉的错误。Java 明智地选择了远离这类错误,并且多年来一直成功地只使用有符号的数字。使用无符号数字的主要原因是某些文件格式或者网络协议的需要。

Float 和 Double 类现在新增了静态方法 isFinite()。如果 x 不是正无穷大、负无穷大或者 NaN(非数字), 那么调用 Double.isFinite(x) 会返回 true。在过去,你不得不调用实例方法 isInFinite 和 isNaN 来获得同样的结果。

最后,BigInteger 类增加了实例方法 (long|int|short|byte) ValueExact, 分别用来返回 long、int、short或者 byte, 并且当值不在目标范围内时抛出一个 ArithmeticException 异常。

  • byte byteValueExact()  将 BigInteger 转换为字节,检查是否丢失信息。

  • shortValueExact()  将 BigInteger 转换为 short,检查是否丢失信息。

  • intValueExact()  将 BigInteger 转换为 int,检查丢失的信息。

  • longValueExact()  将 BigInteger 转换为 long,检查丢失的信息。

说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
公众号