Truyền đôi cho số nguyên trong Java


348

Bất kỳ cách nào để cast java.lang.Doubleđể java.lang.Integer?

Nó ném một ngoại lệ

"java.lang.ClassCastException: java.lang.Double không tương thích với java.lang.Integer"

Câu trả lời:


464

A Doublekhông phải là một Integer, vì vậy các diễn viên sẽ không làm việc. Lưu ý sự khác biệt giữa Double lớpdouble nguyên thủy . Cũng lưu ý rằng a Doublelà a Number, vì vậy nó có phương thức intValue , mà bạn có thể sử dụng để lấy giá trị dưới dạng nguyên thủy int.


2
Ok không để diễn viên. Tôi cần lấy đối tượng Integer từ Double, không phải 13.22222 mà là 13 chẳng hạn.
4lex1v

181
cứ gọi đi intValue().
hvgotcodes

6
Đừng quên xử lý null.
pimlottc

13
Lưu ý rằng điều này chỉ trả về phần nguyên của Double, vì vậy đối với 13.666667 hoặc thậm chí 13.9, bạn sẽ nhận được 13 chứ không phải 14. Nếu bạn muốn số nguyên gần nhất , hãy tham khảo câu trả lời của tôi: stackoverflow.com/a/24816336/1450294
Michael Scheper

2
nếu bạn nhìn vào việc thực hiện intValue(), nó chỉ doublechuyển sang một int.
carlo.marinangeli

565

Bạn cần lấy giá trị int một cách rõ ràng bằng phương thức intValue () như thế này:

Double d = 5.25;
Integer i = d.intValue(); // i becomes 5

Hoặc là

double d = 5.25;
int i = (int) d;

67
Cảm ơn bạn. Rất rõ ràng. Câu trả lời được chấp nhận, đối với tôi, cảm thấy như mắng mỏ khi hỏi một câu hỏi ngớ ngẩn. Nhưng câu trả lời của bạn rất hào phóng.
Buddhaika Ariyaratne

2
Điều gì xảy ra khi giá trị kép nằm ngoài phạm vi số nguyên? (như 2 ^ 33)
nikdeapen

5
Bất kỳ giá trị kép> 2^31 - 1 (Integer.MAX_VALUE)sẽ tràn.
anubhava

3
Và, nhân tiện, khi chuyển từ double sang int, nó chỉ giữ phần nguyên, cho cả số dương & số âm và không quan tâm đến làm tròn. ví dụ như 1.6 -> 1, 1.4 -> 1, -1.6 -> -1, -1.4 -> -1,
Eric Wang

51

Tôi nghĩ rằng không thể hiểu các câu trả lời khác mà không bao gồm những cạm bẫy và lý do đằng sau nó.

Bạn không thể trực tiếp truyền Integermột Doubleđối tượng. Ngoài ra DoubleIntegerlà các đối tượng bất biến, vì vậy bạn không thể sửa đổi chúng theo bất kỳ cách nào.

Mỗi lớp số có một thay thế nguyên thủy ( Doublevs double, Integervs int, ...). Lưu ý rằng những nguyên thủy này bắt đầu bằng một ký tự chữ thường (ví dụ int). Điều đó cho chúng ta biết rằng họ không phải là lớp / đối tượng. Điều đó cũng có nghĩa là họ không có phương pháp. Ngược lại, các lớp (ví dụ Integer) hoạt động như các hộp / hàm bao quanh các nguyên thủy này, điều này cho phép sử dụng chúng như các đối tượng.

Chiến lược:

Để chuyển đổi Doublethành một, Integerbạn cần phải tuân theo chiến lược này:

  1. Chuyển đổi Doubleđối tượng để nguyên thủy double. (= "bỏ hộp")
  2. Chuyển đổi nguyên thủy doublethành nguyên thủy int. (= "đúc")
  3. Chuyển đổi nguyên thủy inttrở lại một Integerđối tượng. (= "quyền anh")

Trong mã:

// starting point
Double myDouble = Double.valueOf(10.0);

// step 1: unboxing
double dbl = myDouble.doubleValue();

// step 2: casting
int intgr = (int) dbl;

// step 3: boxing
Integer val = Integer.valueOf(intgr);

Trên thực tế có một phím tắt. Bạn có thể bỏ hộp ngay lập tức từ Doublethẳng đến nguyên thủy int. Bằng cách đó, bạn có thể bỏ qua bước 2 hoàn toàn.

Double myDouble = Double.valueOf(10.0);
Integer val = Integer.valueOf(myDouble.intValue()); // the simple way

Cạm bẫy:

Tuy nhiên, có rất nhiều điều không được nêu trong đoạn mã trên. Các mã ở trên là không an toàn.

Double myDouble = null;
Integer val = Integer.valueOf(myDouble.intValue()); // will throw a NullPointerException

// a null-safe solution:
Integer val = (myDouble == null)? null : Integer.valueOf(myDouble.intValue());

Bây giờ nó hoạt động tốt cho hầu hết các giá trị. Tuy nhiên, số nguyên có phạm vi rất nhỏ (giá trị tối thiểu / tối đa) so với a Double. Trên hết, nhân đôi cũng có thể giữ "giá trị đặc biệt", số nguyên không thể:

  • 1/0 = + vô cùng
  • -1/0 =
  • 0/0 = không xác định (NaN)

Vì vậy, tùy thuộc vào ứng dụng, bạn có thể muốn thêm một số bộ lọc để tránh Ngoại lệ khó chịu.

Sau đó, thiếu sót tiếp theo là chiến lược làm tròn. Theo mặc định, Java sẽ luôn làm tròn xuống. Làm tròn xuống có ý nghĩa hoàn hảo trong tất cả các ngôn ngữ lập trình. Về cơ bản Java chỉ là bỏ đi một số byte. Trong các ứng dụng tài chính, bạn chắc chắn sẽ muốn sử dụng tính năng làm tròn một nửa (ví dụ: round(0.5) = 1round(0.4) = 0).

// null-safe and with better rounding
long rounded = (myDouble == null)? 0L: Math.round(myDouble.doubleValue());
Integer val = Integer.valueOf(rounded);

Tự động- (un) quyền anh

Bạn có thể bị cám dỗ sử dụng quyền anh tự động (un) trong việc này, nhưng tôi thì không. Nếu bạn đã bị mắc kẹt bây giờ, thì các ví dụ tiếp theo cũng sẽ không rõ ràng. Nếu bạn không hiểu hoạt động bên trong của quyền anh tự động (un) thì xin đừng sử dụng nó.

Integer val1 = 10; // works
Integer val2 = 10.0; // doesn't work

Double val3 = 10; // doesn't work
Double val4 = 10.0; // works

Double val5 = null; 
double val6 = val5; // doesn't work (throws a NullPointerException)

Tôi đoán những điều sau đây không nên là một bất ngờ. Nhưng nếu có, thì bạn có thể muốn đọc một số bài viết về việc truyền trong Java.

double val7 = (double) 10; // works
Double val8 = (Double) Integer.valueOf(10); // doesn't work
Integer val9 = (Integer) 9; // pure nonsense

Thích giá trịOf:

Ngoài ra, không nên sử dụng hàm new Integer()tạo (như một số câu trả lời khác đề xuất). Các valueOf()phương pháp tốt hơn bởi vì họ sử dụng bộ nhớ đệm. Đó là một thói quen tốt để sử dụng các phương pháp này, bởi vì thỉnh thoảng chúng sẽ giúp bạn tiết kiệm bộ nhớ.

long rounded = (myDouble == null)? 0L: Math.round(myDouble.doubleValue());
Integer val = new Integer(rounded); // waste of memory

1
Theo ý kiến ​​của tôi đây là câu trả lời hay nhất
Thor

39

Tôi thấy ba khả năng. Hai chữ số đầu tiên cắt bỏ các chữ số, một vòng cuối cùng đến Số nguyên gần nhất.

double d = 9.5;
int i = (int)d;
//i = 9

Double D = 9.5;
int i = Integer.valueOf(D.intValue());
//i = 9

double d = 9.5;
Long L = Math.round(d);
int i = Integer.valueOf(L.intValue());
//i = 10

21
Không cần Integer.valueOf nếu bạn sẽ lưu trữ kết quả trong một intitit int. Mã của bạn buộc Java thực hiện một hộp và hộp không cần thiết.
bvdb


23

Thật vậy, cách đơn giản nhất là sử dụng intValue(). Tuy nhiên, điều này chỉ trả về phần nguyên; nó không làm tròn được. Nếu bạn muốn Số nguyên gần nhất với giá trị Double, bạn sẽ cần thực hiện việc này:

Integer integer = Integer.valueOf((int) Math.round(myDouble)));

Và đừng quên trường hợp null:

Integer integer = myDouble == null ? null : Integer.valueOf((int) Math.round(myDouble)));

Math.round() xử lý các trường hợp vịt kỳ lạ, như vô cực và NaN, với ân sủng tương đối.


2
Tại sao bạn cần Integer.valueOf nếu bạn truyền kết quả Math.round cho int?
Eran H.

@EranH.: Kể từ Java 1.5, có lẽ bạn không tự động hóa hộp số có nghĩa là mã có thể sẽ làm điều tương tự theo cách nào đó. Nhưng tôi nghĩ mã này rõ ràng hơn cho những người chưa nắm bắt được các đối tượng và nguyên thủy.
Michael Scheper

Bất cứ ai đã bỏ phiếu trả lời câu trả lời này: Bạn sẽ giúp cộng đồng nhiều hơn nữa nếu bạn giải thích lý do và thậm chí nó có thể giúp bạn tìm ra lý do tại sao nó không hiệu quả với bạn. Bỏ phiếu mà không có lời giải thích, OTOH, là không có ích cho tất cả mọi người, và nó đi qua như hèn nhát.
Michael Scheper

14
double a = 13.34;
int b = (int) a;

System.out.println(b); //prints 13

2
Câu hỏi cụ thể là về các lớp bao bọc. Câu trả lời này là về người nguyên thủy.
Michael Scheper

8

Đơn giản chỉ cần làm theo cách này ...

Double d = 13.5578;
int i = d.intValue();
System.out.println(i);

7
Double d = 100.00;
Integer i = d.intValue();

Người ta cũng nên thêm rằng nó hoạt động với autoboxing.

Mặt khác, bạn nhận được một int (nguyên thủy) và sau đó có thể nhận được một Integer từ đó:

Integer i = new Integer(d.intValue());

2
Không sử dụng new Integer(int), thay vào đó sử dụng Integer.valueOf(int), có bộ đệm cho các số nguyên nhỏ, chẳng hạn như số nguyên này.
bvdb


4

Bạn có thể làm điều đó bằng cách sử dụng "Thu hẹp hoặc chuyển đổi loại rõ ràng", gấp đôi → dài → int. Tôi hy vọng nó sẽ làm việc.

double d = 100.04;
long l = (long)d; // Explicit type casting required
int i = (int)l;    // Explicit type casting required

PS: Nó sẽ cho 0 vì double có tất cả các giá trị thập phân và không có gì ở phía bên trái. Trong trường hợp 0,58, nó sẽ thu hẹp xuống còn 0. Nhưng đối với những người khác, nó sẽ làm nên điều kỳ diệu.


4

Hãy thử cái này

double doubleValue = 6.5;Double doubleObj = new Double(doubleValue);int intResult = doubleObj.intValue();

3

Double và Integer là các lớp trình bao bọc cho các nguyên hàm Java cho double và int tương ứng. Bạn có thể bỏ giữa những thứ đó, nhưng bạn sẽ mất điểm nổi. Nghĩa là, 5,4 được chuyển thành int sẽ là 5. Nếu bạn bỏ nó lại, nó sẽ là 5.0.


0

Chỉ cần sử dụng phương pháp intValue của Double

Double initialValue = 7.12;
int finalValue = initialValue.intValue();

2
Có vẻ như lặp lại các câu trả lời khác.
Pang

0

Sử dụng doubleNumber.intValue();phương pháp.


2
Có vẻ như lặp lại các câu trả lời khác.
Pang

-1

Bộ nhớ hiệu quả, vì nó sẽ chia sẻ thể hiện đã tạo của Double.

Double.valueOf(Math.floor(54644546464/60*60*24*365)).intValue()

Có bất kỳ lý do cho Math.floor(...)? intValue()luôn luôn tầng nào.
bvdb

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.