java.lang.Long.signum(long i)
是 Java 中用于获取 long
类型数值符号函数(Sign Function) 的静态方法。它返回一个整数值,表示指定 long
值的符号:正数、负数或零。该方法在数学计算、排序逻辑、条件判断和数值分析中非常有用,能够简洁地判断一个数的正负性。
一、方法定义
public static int signum(long i)
- 类:
java.lang.Long
- 参数:
long i
—— 要检查符号的长整型值 - 返回值:
int
类型,含义如下:1
:如果i > 0
0
:如果i == 0
-1
:如果i < 0
- 异常:无
- 自版本:JDK 1.5
🔗 类似方法:
Integer.signum(int i)
Math.signum(double/float)
(返回double
)
二、功能说明
signum
是数学中的符号函数,定义为:
signum(x) = 1, if x > 0
0, if x == 0
-1, if x < 0
Long.signum()
正是这一函数在 long
类型上的实现。它不关心数值大小,只关注其符号。
三、示例代码
public class LongSignumExample {
public static void main(String[] args) {
// 正数
System.out.println(Long.signum(100L)); // 输出: 1
System.out.println(Long.signum(1L)); // 输出: 1
System.out.println(Long.signum(Long.MAX_VALUE)); // 输出: 1
// 零
System.out.println(Long.signum(0L)); // 输出: 0
// 负数
System.out.println(Long.signum(-1L)); // 输出: -1
System.out.println(Long.signum(-100L)); // 输出: -1
System.out.println(Long.signum(Long.MIN_VALUE)); // 输出: -1
// 常见用途:判断正负
long value = -50L;
int sign = Long.signum(value);
if (sign == 1) {
System.out.println("正数");
} else if (sign == -1) {
System.out.println("负数");
} else {
System.out.println("零");
}
// 输出: 负数
}
}
四、使用技巧
1. 简化条件判断
// 代替复杂的 if-else 判断
if (Long.signum(x) == Long.signum(y)) {
System.out.println("x 和 y 同号");
}
2. 排序比较器中的符号提取
Comparator<Long> comparator = (a, b) -> Long.signum(a - b);
// 注意:a - b 可能溢出,更安全写法见下文
3. 数学计算中的符号控制
long magnitude = 100L;
long direction = -1L;
long result = magnitude * Long.signum(direction); // -100
4. 与 Math.signum()
对比使用
double d = -123.45;
int signFromMath = (int) Math.signum(d); // -1
int signFromLong = Long.signum((long) d); // -1
5. 安全的比较器写法(避免溢出)
Comparator<Long> safeComparator = (a, b) -> {
if (a < b) return -1;
if (a > b) return 1;
return 0;
};
// 或使用 Integer.signum(Long.compare(a, b))
五、常见错误
错误 | 说明 |
---|---|
误用 a - b 作为 signum 参数 |
long 减法可能溢出,导致符号错误 |
混淆返回类型 | 返回 int 而非 long |
认为 signum 可用于浮点数 |
应使用 Math.signum(double) 处理浮点数 |
忽略 Long.MIN_VALUE 特殊性 |
其绝对值大于 Long.MAX_VALUE ,但 signum 正常返回 -1 |
错误示例(溢出):
long a = Long.MAX_VALUE;
long b = -1L;
// ❌ a - b 溢出为负数,signum 返回 -1,逻辑错误
int wrongSign = Long.signum(a - b); // -1,但 a > b
六、注意事项
- ✅ 无异常抛出:任何
long
值(包括MIN_VALUE
,MAX_VALUE
,0
)都合法。 - ⚠️ 减法溢出风险:不要将
a - b
直接传给signum
来比较大小。 - ✅ 性能极高:内部实现为简单条件判断,接近常数时间
O(1)
。 - ✅ 线程安全:静态无状态方法,可并发调用。
- ✅ 精度无损失:
long
是整型,无浮点精度问题。
七、最佳实践
用于符号判断,而非大小比较
// ✅ 好:判断符号 if (Long.signum(value) < 0) { /* 负数 */ } // ❌ 坏:用于比较(可能溢出) // if (Long.signum(a - b) > 0) { /* a > b */ }
安全比较使用
Long.compare(a, b)
int cmp = Long.compare(a, b); // 返回 -1, 0, 1
与
Math.abs()
结合使用long absValue = Math.abs(value); int sign = Long.signum(value); long original = absValue * sign; // 恢复符号(注意:Long.MIN_VALUE 除外)
在泛型或函数式编程中作为映射函数
List<Long> numbers = Arrays.asList(10L, -5L, 0L, -1L); List<Integer> signs = numbers.stream() .map(Long::signum) .toList(); // [1, -1, 0, -1]
八、性能优化
极高效,无需优化
signum
内部是几个条件判断,性能已最优。
避免重复调用
// ❌ if (Long.signum(x) == 1) { ... } process(Long.signum(x)); // ✅ int sign = Long.signum(x); if (sign == 1) { ... } process(sign);
在热点代码中可内联(JVM 自动优化)
- 无需手动展开。
九、总结
特性 | 说明 |
---|---|
方法 | Long.signum(long i) |
返回值 | 1 (正)、0 (零)、-1 (负) |
用途 | 判断 long 值的符号 |
性能 | 极高,O(1),无对象创建 |
安全性 | 无异常,支持所有 long 值 |
核心要点:
- ✅ 只关心符号,不关心大小。
- ✅ 返回值为
int
,但语义清晰。 - ⚠️ 禁止用
a - b
计算差值符号(溢出风险)。 - 🔄 与
Long.compare(a, b)
配合使用更安全。 - 🚀 性能卓越,适合高频调用场景。