streams - ¿Cómo usar el entero sin signo en Java 8 y Java 9?
java 8 tutorial (5)
Bueno, incluso en Java 8, long
e int
todavía están firmados, solo algunos métodos los tratan como si no estuvieran firmados . Si quieres escribir un texto long
sin firmar como ese, puedes hacer
static long values = Long.parseUnsignedLong("18446744073709551615");
public static void main(String[] args) {
System.out.println(values); // -1
System.out.println(Long.toUnsignedString(values)); // 18446744073709551615
}
En la página de Oracle "tipos de datos primitivos", menciona que Java 8 agrega compatibilidad con ints y longs sin firmar:
int
: de forma predeterminada, el tipo de datosint
es un entero de complemento de dos firmado de 32 bits, que tiene un valor mínimo de -2 31 y un valor máximo de 2 31 -1. En Java SE 8 y posterior, puede usar el tipo de datosint
para representar un entero de 32 bits sin signo, que tiene un valor mínimo de 0 y un valor máximo de 2 32 -1. Utilice la claseInteger
para usar el tipo de datosint
como un entero sin signo. Vea la sección The Number Classes para más información. Los métodos estáticos comocompareUnsigned
,compareUnsigned
, etc. se han agregado a la claseInteger
para admitir las operaciones aritméticas para enteros sin signo.
long
: el tipo de datoslong
es un entero complementario de dos de 64 bits. Ellong
firmado tiene un valor mínimo de -2 63 y un valor máximo de 2 63 -1. En Java SE 8 y posteriores, puede usar el tipo de datoslong
para representar unlong
sin signo de 64 bits, que tiene un valor mínimo de 0 y un valor máximo de 2 64 -1. Utilice este tipo de datos cuando necesite un rango de valores más amplio que los provistos por int. La claseLong
también contiene métodos comocompareUnsigned
,divideUnsigned
, etc. para admitir operaciones aritméticas para unsignedlong
.
Sin embargo, no encuentro forma de declarar un entero o un entero sin signo. El siguiente código, por ejemplo, da un mensaje de error del compilador de "el literal está fuera de rango" (estoy usando Java 8, por supuesto), cuando debería estar dentro del rango (el valor asignado es precisamente 2 64 -1) :
public class Foo {
static long values = 18446744073709551615L;
public static void main(String[] args){
System.out.println(values);
}
}
Entonces, ¿hay alguna manera de declarar unsigned int o long?
No hay forma de cómo declarar page en Java 8 o Java 9. Pero algunos métodos los tratan como si no hubieran sido firmados, por ejemplo:
static long values = Long.parseUnsignedLong("123456789012345678");
pero esta no es una declaration de la variable.
Según la documentación que publicaste, y esta publicación en el blog , no hay diferencia al declarar la primitiva entre un int / long sin firmar y uno firmado. El "nuevo soporte" es la adición de los métodos estáticos en las clases Integer y Long, por ejemplo, Integer.divideUnsigned . Si no está utilizando esos métodos, su "unsigned" mucho más arriba de 2 ^ 63-1 es simplemente un antiguo simple con un valor negativo.
Desde un destello rápido, no parece que haya una forma de declarar constantes enteras en el rango fuera de +/- 2 ^ 31-1, o +/- 2 ^ 63-1 para longs. Debería calcular manualmente el valor negativo correspondiente a su valor positivo fuera de rango.
Si usar una biblioteca de terceros es una opción, existe jOOU (una biblioteca derivada de jOOQ ), que ofrece tipos de contenedor para números enteros sin signo en Java. Eso no es exactamente lo mismo que tener soporte de tipo primitivo (y por lo tanto de código de bytes) para tipos sin firmar, pero tal vez todavía sea lo suficientemente bueno para su caso de uso.
import static org.joou.Unsigned.*;
// and then...
UByte b = ubyte(1);
UShort s = ushort(1);
UInteger i = uint(1);
ULong l = ulong(1);
Todos estos tipos amplían java.lang.Number
y se pueden convertir en tipos de primitiva de orden superior y BigInteger
.
(Descargo de responsabilidad: yo trabajo para la compañía detrás de estas bibliotecas)
// Java 8
int vInt = Integer.parseUnsignedInt("4294967295");
System.out.println(vInt); // -1
String sInt = Integer.toUnsignedString(vInt);
System.out.println(sInt); // 4294967295
long vLong = Long.parseUnsignedLong("18446744073709551615");
System.out.println(vLong); // -1
String sLong = Long.toUnsignedString(vLong);
System.out.println(sLong); // 18446744073709551615
// Guava 18.0
int vIntGu = UnsignedInts.parseUnsignedInt(UnsignedInteger.MAX_VALUE.toString());
System.out.println(vIntGu); // -1
String sIntGu = UnsignedInts.toString(vIntGu);
System.out.println(sIntGu); // 4294967295
long vLongGu = UnsignedLongs.parseUnsignedLong("18446744073709551615");
System.out.println(vLongGu); // -1
String sLongGu = UnsignedLongs.toString(vLongGu);
System.out.println(sLongGu); // 18446744073709551615
/**
Integer - Max range
Signed: From −2,147,483,648 to 2,147,483,647, from −(2^31) to 2^31 – 1
Unsigned: From 0 to 4,294,967,295 which equals 2^32 − 1
Long - Max range
Signed: From −9,223,372,036,854,775,808 to 9,223,372,036,854,775,807, from −(2^63) to 2^63 − 1
Unsigned: From 0 to 18,446,744,073,709,551,615 which equals 2^64 – 1
*/