Jak przekonwertować long na int w Javie?

Odpowiedzi:

371

Zaktualizowano w Javie 8:

Math.toIntExact(value);

Oryginalna odpowiedź:

Prosty typ odlewania powinien to zrobić:

long l = 100000;
int i = (int) l;

Należy jednak pamiętać, że duże liczby (zwykle większe niż 2147483647i mniejsze niż -2147483648) utracą niektóre bity i będą niepoprawnie reprezentowane.

Na przykład 2147483648byłby reprezentowany jako -2147483648.

Frxstrem
źródło
Jaka jest precyzja liczb całkowitych? o_O
khachik
3
@khachik Myślę, że precyzja wynosi 1. A może 42 oczywiście :)
extraneon
7
Rzutowanie ma różne znaczenie dla obiektów i typów prymitywnych. (int) l nie próbuje traktować 64-bitowej liczby całkowitej jako 32-bitowej liczby całkowitej, w rzeczywistości zwraca inną 32-bitową liczbę całkowitą z tymi samymi 32 bitami niższego rzędu. W przypadku obiektów rzutujesz na bardziej określoną klasę potomną, ale w przypadku typów pierwotnych rzutowanie nie jest tak naprawdę rzutowaniem, ale konwersją.
dspyz
Int x = (int) (((Long) Integer.MAX_INTEGER) +10); Jeśli konwersja nie wykryje w tym przypadku, że x ma niepoprawną wartość, to nie masz rozwiązania.
raisercostin
Math.toIntExact () jest w rzeczywistości świetną metodą. Zgłasza i wyjątek, jeśli wartość jest zbyt duża, aby zmieścić się w wartości int. Dzieki za sugestie.
java-addict301
182
Long x = 100L;
int y = x.intValue();

Laxman
źródło
3
Powiedziałbym, że to będzie najlepszy sposób.
Simmant,
Jaka jest różnica między tym sposobem a po prostu rzuceniem wartości? Myślę, że wszystko, co intValue()tu w tle rzuca, ma wartość… Tak?
Tim Wißmann
1
Zwróć uwagę na typy. To nie jest prymitywne longtutaj. Jest to typ odniesienia, Longktóry nie może bezpośrednio rzutować na prymityw int. int y = (int)x;wyrzuci wykonanie, ale int y = (int)(long)xzadziała. (Powodem jest autoboxing)
akop
58

W przypadku małych wartości wystarczy rzutowanie:

long l = 42;
int i = (int) l;

Jednak longmoże zawierać więcej informacji niż an int, więc w ogólnym przypadku nie można idealnie przekonwertować z longna int. Jeśli longliczba jest mniejsza lub równa Integer.MAX_VALUE, możesz ją przekonwertować, przesyłając bez utraty jakichkolwiek informacji.

Na przykład następujący przykładowy kod:

System.out.println( "largest long is " + Long.MAX_VALUE );
System.out.println( "largest int is " + Integer.MAX_VALUE );

long x = (long)Integer.MAX_VALUE;
x++;
System.out.println("long x=" + x);

int y = (int) x;
System.out.println("int y=" + y);

produkuje następujące dane wyjściowe na moim komputerze:

largest long is 9223372036854775807
largest int is 2147483647
long x=2147483648
int y=-2147483648

Zwróć uwagę na znak ujemny na y. Ponieważ xposiadał wartość o jeden większą niż Integer.MAX_VALUE, int ynie mógł go utrzymać. W tym przypadku zawinął się do liczb ujemnych.

Jeśli chcesz samodzielnie zająć się tą sprawą, możesz zrobić coś takiego:

if ( x > (long)Integer.MAX_VALUE ) {
    // x is too big to convert, throw an exception or something useful
}
else {
    y = (int)x;
}

Wszystko to zakłada liczby dodatnie. W przypadku liczb ujemnych użyj MIN_VALUEzamiast `MAX_VALUE '

mndrix
źródło
Tak więc poprawną konwersją będzie wykrycie, czy konwersja jest bezpieczna i odrzucenie wyjątku w inny sposób. Fakt podany przez @Andreja Hericha, który sugerował bibliotekę Guava.
raisercostin
55

Od wersji Java 8 możesz używać: Math.toIntExact (długa wartość)

Zobacz JavaDoc: Math.toIntExact

Zwraca wartość długiego argumentu; zgłaszanie wyjątku, jeśli wartość przepełnia wartość int.

Kod źródłowy Math.toIntExactw JDK 8:

public static int toIntExact(long value) {
    if ((int)value != value) {
        throw new ArithmeticException("integer overflow");
    }
    return (int)value;
}
Kuchi
źródło
37

W przypadku korzystania z biblioteki Guava , istnieją metody Ints.checkedCast(long)i Ints.saturatedCast(long)przekształcania longsię int.

Andrej Herich
źródło
4
Nie ma potrzeby korzystania z bibliotek
Grekz,
6
@Grekz to zależy od OP. Zrobiłbym w tym przypadku. Więcej słoików zależności jest lepszych niż więcej wymyślonych kół, chyba że masz rzeczywisty powód, aby nie mieć więcej słoików zależności.
djechlin
1
IMHO, ta odpowiedź jest znacznie lepsza niż zaakceptowana, ponieważ nigdy nie robi czegoś nieoczekiwanego.
Mark Slater,
5
Ponieważ mój projekt zawiera już ten słoik, korzystniej byłoby go użyć niż napisać nowego pomocnika
Osify
24
long x = 3;
int y = (int) x;

ale zakłada to, że longmożna to przedstawić jako int, czy znasz różnicę między nimi?

Theo
źródło
6
Interesujące jest to, że zgodnie z par 5.1.3 w java.sun.com/docs/books/jls/third_edition/html/… (Specyfikacja języka Java): Pomimo faktu, że przepełnienie, niedopełnienie lub inna utrata informacji może występuje, zawężenie konwersji między typami pierwotnymi nigdy nie powoduje wyjątku w czasie wykonywania (§11).
extraneon
18

Możesz użyć Longopakowania zamiast operacji longpodstawowej i wywołania

Long.intValue()

Dokumenty Java7 intValue ()

To rund / obciąć longwartości odpowiednio dopasować w sposób int.

eleonzx
źródło
Dobrym pomysłem może być link do bieżącej dokumentacji, a także jej rozwinięcie - nieuchronnie będzie zaokrąglanie przy konwersji długiej na int.
Makoto
2
Patrząc na implementację Long.intValue () w Javie 7, to tylko rzutowanie. Nie jest stosowane sprawdzanie niedopełnienia / przepełnienia. Tak więc przynajmniej przez Javę 7 ta opcja jest odpowiednikiem tylko: (int) someLong.
buzz3791
dlaczego mniej pozytywnych opinii? Znalazłem jedną z najcenniejszych odpowiedzi
Anand J. Kadhi
3

Jeśli bezpośredni rzutowanie pokazuje błąd, możesz to zrobić w następujący sposób:

Long id = 100;
int int_id = (int) (id % 100000);
Mohammad H.
źródło
2

W Javie długi jest liczbą 64-bitową ze znakiem, co oznacza, że ​​możesz przechowywać liczby od -9 223 372,036,854,775,808 do 9 223 372,036,854,775,807 (włącznie).

Z drugiej strony, int jest oznaczony liczbą 32-bitową, co oznacza, że ​​możesz przechowywać liczbę między -2 147 483 648 a 2 147 483 647 (włącznie).

Więc jeśli twój long jest poza wartościami dopuszczalnymi dla int, nie uzyskasz wartościowej konwersji.

Szczegóły dotyczące rozmiarów prymitywnych typów Java tutaj:

http://download.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html

Alexis Dufrenoy
źródło
1
Odpowiedzi na pytanie już udzieliłem w chwili, gdy je zobaczyłem, ale temat granic konwersji nie został wyjaśniony. Co wtedy zrobiłem. Jeśli uważasz, że to „bla bla bla”, oznacza to tylko, że jesteś jakimś geniuszem, który może się obejść bez tego rodzaju rzeczy, ale dla nas, zwykłych ludzi, wyjaśnienie może być przydatne. Dziękuję za „wejście” ...
Alexis Dufrenoy,
1

W Javie 8 robię to w następujący sposób

long l = 100L;
int i = Math.toIntExact(l);

Ta metoda wyrzuca, ArithmaticExceptionjeśli longwartość przekroczy zakres int. Dlatego jestem bezpieczny przed utratą danych.

Emdadul Sawon
źródło
0

Jeśli chcesz dokonać bezpiecznej konwersji i cieszyć się użyciem Java8 z wyrażeniem Lambda, możesz użyć go w następujący sposób:

val -> Optional.ofNullable(val).map(Long::intValue).orElse(null)
użytkownik13651274
źródło
Chcesz powiedzieć, że tak Function<Long,Integer> function =?
Scratte
-1

długie x = 3120L; // weź dowolną długą wartość int z = x.intValue (); // możesz przekonwertować double na int również w ten sam sposób

jeśli trzeba to ukryć bezpośrednio, to

longvalue.intvalue ();

MANOJ G.
źródło
To źle, 3.120 nie jest długi, jest liczbą podwójną lub zmiennoprzecinkową.
George Xavier
-4
Long l = 100;
int i = Math.round(l);
Kristijan Drača
źródło
-7

Na wiosnę istnieje rygorystyczny sposób konwersji długiej na int

nie tylko lnog może konwertować na int, każdy typ rozszerza klasę Liczba może konwertować na inny typ liczbowy ogólnie, tutaj pokażę, jak przekonwertować long na int, inny typ vice versa.

Long l = 1234567L;
int i = org.springframework.util.NumberUtils.convertNumberToTargetClass(l, Integer.class);

konwertuj long na int

tsaowe
źródło
6
Wiosna może być Javą, ale Java nie jest wiosną. „W java istnieje” to fałszywe stwierdzenie.
Gordon