在Java中安全地将long转换为int
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在Java中安全地将long转换为int相关的知识,希望对你有一定的参考价值。
在Java中验证从long
到int
的演员阵容不会丢失任何信息的最惯用的方法是什么?
这是我目前的实施:
public static int safeLongToInt(long l) {
int i = (int)l;
if ((long)i != l) {
throw new IllegalArgumentException(l + " cannot be cast to int without changing its value.");
}
return i;
}
Java 8添加了一种新方法来实现这一目标。
import static java.lang.Math.toIntExact;
long foo = 10L;
int bar = toIntExact(foo);
如果溢出,将抛出ArithmeticException
。
Java 8中添加了其他几种溢出安全方法。它们以精确结尾。
例子:
Math.incrementExact(long)
Math.subtractExact(long, long)
Math.decrementExact(long)
Math.negateExact(long),
Math.subtractExact(int, int)
另一个解决方案可以是:
public int longToInt(Long longVariable)
{
try {
return Integer.valueOf(longVariable.toString());
} catch(IllegalArgumentException e) {
Log.e(e.printstackstrace());
}
}
我已经尝试过这种情况,客户端正在进行POST,而服务器数据库只能理解Integers,而客户端只有Long。
我想我会这样做:
public static int safeLongToInt(long l) {
if (l < Integer.MIN_VALUE || l > Integer.MAX_VALUE) {
throw new IllegalArgumentException
(l + " cannot be cast to int without changing its value.");
}
return (int) l;
}
我认为比重复铸造更清楚地表达了意图......但它有点主观。
注意潜在的兴趣 - 在C#中它只是:
return checked ((int) l);
使用Google Guava的Ints类,您的方法可以更改为:
public static int safeLongToInt(long l) {
return Ints.checkedCast(l);
}
来自链接的文档:
checkedCast时
public static int checkedCast(long value)
如果可能,返回等于
value
的int值。参数:
value
-int
类型范围内的任何值返回:
int
值等于value
投掷:
IllegalArgumentException
- 如果value
大于Integer.MAX_VALUE
或小于Integer.MIN_VALUE
顺便说一句,你不需要safeLongToInt
包装器,除非你想在不进行大量重构的情况下更改功能。
使用BigDecimal:
long aLong = ...;
int anInt = new BigDecimal(aLong).intValueExact(); // throws ArithmeticException
// if outside bounds
这是一个解决方案,如果你不关心价值,以防它需要更大;)
public static int safeLongToInt(long l) {
return (int) Math.max(Math.min(Integer.MAX_VALUE, l), Integer.MIN_VALUE);
}
不要:这不是解决方案!
我的第一个方法是:
public int longToInt(long theLongOne) {
return Long.valueOf(theLongOne).intValue();
}
但这只是将长时间转换为int,可能会创建新的Long
实例或从Long池中检索它们。
缺点
- 如果数字不在
Long.valueOf
的游泳池范围内,Long
会创建一个新的Long
实例[-128,127]。 intValue
的实现只不过是:return (int)value;
因此,这可以被认为比仅仅将long
投射到int
更糟糕。
我声称看到是否更改值的显而易见的方法是转换并检查结果。但是,我会在比较时删除不必要的演员表。我也不太热衷于一个字母变量名称(例外x
和y
,但不是当它们意味着行和列(有时分别))。
public static int intValue(long value) {
int valueInt = (int)value;
if (valueInt != value) {
throw new IllegalArgumentException(
"The long value "+value+" is not within range of the int type"
);
}
return valueInt;
}
但是,如果可能的话,我真的想避免这种转换。显然有时它是不可能的,但在那些情况下,就客户端代码而言,IllegalArgumentException
几乎肯定是错误的例外。
Java整数类型表示为signed。如果输入介于231和232(或-231和-232)之间,则演员会成功,但您的测试将失败。
要检查的是long
的所有高位是否都是相同的:
public static final long LONG_HIGH_BITS = 0xFFFFFFFF80000000L;
public static int safeLongToInt(long l) {
if ((l & LONG_HIGH_BITS) == 0 || (l & LONG_HIGH_BITS) == LONG_HIGH_BITS) {
return (int) l;
} else {
throw new IllegalArgumentException("...");
}
}
(int) (longType + 0)
但龙不能超过最大值:)
以上是关于在Java中安全地将long转换为int的主要内容,如果未能解决你的问题,请参考以下文章
如何在 R 中毫无问题地将 Lat-Long 转换为 FIPS 县代码?
java中long型如何转换为int型?还有long[ ]可以转换为int吗?
安全地将 std::string_view 转换为 int(如 stoi 或 atoi)