Cast Double to Integer ใน Java


348

มีวิธีใดบ้างที่จะส่งjava.lang.Doubleไปjava.lang.Integer?

มันส่งข้อยกเว้น

"java.lang.ClassCastException: java.lang.Double เข้ากันไม่ได้กับ java.lang.Integer"

คำตอบ:


464

A Doubleไม่ได้เป็นIntegerดังนั้นนักแสดงจะไม่ทำงาน หมายเหตุ: ความแตกต่างระหว่างDouble ระดับและดั้งเดิมdouble นอกจากนี้ยังทราบว่าDoubleเป็นNumber, ดังนั้นจึงมีวิธีการ ที่คุณสามารถใช้เพื่อให้ได้ค่าที่เป็นแบบดั้งเดิมintValueint


2
ตกลงที่จะไม่ร่าย ฉันต้องได้วัตถุจำนวนเต็มจาก Double ไม่ใช่ 13.22222 แต่เป็น 13
4lex1v

181
เพียงแค่โทรintValue()แล้ว
hvgotcodes

6
อย่าลืมจัดการ nulls
pimlottc

13
โปรดทราบว่านี่แค่คืนค่าจำนวนเต็มของ Double ดังนั้นสำหรับ 13.666667 หรือแม้กระทั่ง 13.9 คุณจะได้ 13 ไม่ใช่ 14 ถ้าคุณต้องการจำนวนเต็มที่ใกล้เคียงที่สุดให้อ้างอิงคำตอบของฉัน: stackoverflow.com/a/24816336/1450294
Michael Scheper

2
ถ้าคุณมองไปที่การดำเนินงานของintValue()มันก็ปลดเปลื้องไปยังdouble int
carlo.marinangeli

566

คุณจำเป็นต้องรับค่า int โดยใช้ method intValue () ดังนี้:

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

หรือ

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

67
ขอบคุณ. ชัดเจนมาก คำตอบที่ยอมรับได้สำหรับฉันรู้สึกดุด่าว่าถามคำถามโง่ ๆ แต่คำตอบของคุณใจดีมาก
Buddhika Ariyaratne

2
จะเกิดอะไรขึ้นเมื่อค่า double อยู่นอกช่วงจำนวนเต็ม (เช่น 2 ^ 33)
nikdeapen

5
ค่าสองเท่าใด ๆ > 2^31 - 1 (Integer.MAX_VALUE)จะล้น
anubhava

3
และโดยวิธีการเมื่อทำการร่ายจาก double ถึง int มันจะเก็บเฉพาะจำนวนเต็มเท่านั้นสำหรับทั้งจำนวนบวกและลบและไม่สนใจการปัดเศษ เช่น1.6 -> 1, 1.4 -> 1, -1.6 -> -1, -1.4 -> -1,
เอริควัง

51

ฉันคิดว่ามันเป็นไปไม่ได้ที่จะเข้าใจคำตอบอื่น ๆ โดยไม่ปิดบังหลุมพรางและให้เหตุผลเบื้องหลัง

คุณไม่สามารถโยนวัตถุIntegerไปยังDoubleวัตถุโดยตรง นอกจากนี้DoubleและIntegerเป็นวัตถุที่ไม่เปลี่ยนรูปดังนั้นคุณจึงไม่สามารถแก้ไขได้ในทางใดทางหนึ่ง

คลาสตัวเลขแต่ละคลาสมีทางเลือกดั้งเดิม ( Doublevs double, Integervs int, ... ) โปรดทราบว่าคำสั่งดั้งเดิมเหล่านี้เริ่มต้นด้วยอักขระตัวพิมพ์เล็ก (เช่นint) นั่นบอกเราว่าพวกเขาไม่ได้เรียน / วัตถุ ซึ่งหมายความว่าพวกเขาไม่มีวิธี ในทางตรงกันข้ามคลาส (เช่นInteger) ทำหน้าที่เหมือนกล่อง / ตัวล้อมรอบดั้งเดิมซึ่งทำให้สามารถใช้พวกมันเหมือนวัตถุ

กลยุทธ์:

การแปลงDoubleไปสู่การIntegerที่คุณจะต้องทำตามกลยุทธ์นี้:

  1. แปลงวัตถุโบราณDouble double(= "ยกเลิกการทำกล่อง")
  2. แปลงดั้งเดิมเพื่อดั้งเดิมdouble int(= "แคสติ้ง")
  3. แปลงดั้งเดิมintกลับไปเป็นIntegerวัตถุ (= "มวย")

ในรหัส:

// 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);

จริงๆแล้วมีทางลัด คุณสามารถ unbox ทันทีจากตรงไปยังดั้งเดิมDouble intด้วยวิธีนี้คุณสามารถข้ามขั้นตอนที่ 2 ได้ทั้งหมด

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

ผิดพลาด:

อย่างไรก็ตามมีหลายสิ่งหลายอย่างที่ไม่ได้กล่าวถึงในรหัสข้างต้น รหัสข้างต้นไม่ปลอดภัย

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());

ตอนนี้มันทำงานได้ดีสำหรับค่าส่วนใหญ่ อย่างไรก็ตามจำนวนเต็มมีช่วงที่มีขนาดเล็กมาก (นาที / ค่าสูงสุด) Doubleเมื่อเทียบกับ ยิ่งไปกว่านั้นคู่ยังสามารถถือ "ค่าพิเศษ" จำนวนเต็มที่ไม่สามารถ:

  • 1/0 = + อินฟินิตี้
  • -1/0 = -infinity
  • 0/0 = ไม่ได้กำหนด (NaN)

ดังนั้นขึ้นอยู่กับแอปพลิเคชันคุณอาจต้องการเพิ่มตัวกรองบางอย่างเพื่อหลีกเลี่ยงข้อยกเว้นที่น่ารังเกียจ

จากนั้นข้อบกพร่องถัดไปคือกลยุทธ์การปัดเศษ ตามค่าเริ่มต้น Java จะปัดเศษเสมอ การปัดเศษลงทำให้รู้สึกที่สมบูรณ์แบบในทุกภาษาการเขียนโปรแกรม โดยพื้นฐานแล้ว Java กำลังจะทิ้งบางส่วนของไบต์ ในแอปพลิเคชั่นทางการเงินคุณจะต้องใช้การปัดเศษครึ่งตัว (เช่น: round(0.5) = 1และround(0.4) = 0)

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

อัตโนมัติ (UN) มวย

คุณอาจถูกล่อลวงให้ใช้มวยอัตโนมัติ (ไม่)ในนี้ แต่ฉันจะไม่ทำ หากคุณติดอยู่ในขณะนี้ตัวอย่างต่อไปจะไม่ชัดเจน หากคุณไม่เข้าใจผลงานภายในของมวยอัตโนมัติ (ไม่) โปรดอย่าใช้มัน

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)

ฉันเดาว่าสิ่งต่อไปนี้ไม่น่าแปลกใจ แต่ถ้าเป็นเช่นนั้นคุณอาจต้องการอ่านบทความเกี่ยวกับการคัดเลือกนักแสดงใน Java

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

ชอบมูลค่าของ:

นอกจากนี้อย่าล่อลวงให้ใช้ตัวnew Integer()สร้าง (ตามคำตอบอื่น ๆ ที่เสนอ) valueOf()วิธีการจะดีกว่าเพราะพวกเขาใช้แคช เป็นนิสัยที่ดีที่จะใช้วิธีการเหล่านี้เพราะบางครั้งพวกเขาจะช่วยให้คุณประหยัดความทรงจำ

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

1
ในความคิดของฉันเป็นคำตอบที่ดีที่สุด
ธ อร์

39

ฉันเห็นความเป็นไปได้สามอย่าง สองคนแรกตัดตัวเลขหนึ่งรอบสุดท้ายเป็นจำนวนเต็มที่ใกล้ที่สุด

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
ไม่จำเป็นต้องมี Integer.valueOf หากคุณต้องการเก็บผลลัพธ์ไว้ใน primitieve int รหัสของคุณบังคับให้ Java ดำเนินการในกล่องและ unbox ที่ไม่จำเป็น
bvdb


23

intValue()อันที่จริงวิธีที่ง่ายที่สุดคือการใช้งาน อย่างไรก็ตามนี่แค่คืนค่าจำนวนเต็ม มันไม่ได้ทำการปัดเศษใด ๆ หากคุณต้องการจำนวนเต็มใกล้เคียงกับค่า Double คุณจะต้องทำสิ่งนี้:

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

และอย่าลืมกรณี null:

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

Math.round() จัดการกับกรณีเป็ดแปลก ๆ เช่นอินฟินิตี้และน่านด้วยพระคุณญาติ


2
ทำไมคุณต้องมี Integer.valueOf ถ้าคุณส่งผล Math.round ไปยัง int?
Eran H.

@EranH: ในฐานะของ Java 1.5 คุณอาจไม่ได้ - การล็อกอัตโนมัติหมายความว่าโค้ดน่าจะจบลงด้วยการทำสิ่งเดียวกันด้วยวิธีใดวิธีหนึ่ง แต่ฉันคิดว่ารหัสนี้มีความชัดเจนสำหรับผู้ที่ยังไม่เข้าใจวัตถุและสิ่งดั้งเดิม
Michael Scheper

ใครก็ตามที่โหวตคำตอบนี้: คุณจะช่วยชุมชนได้มากขึ้นถ้าคุณอธิบายว่าทำไมและมันอาจช่วยให้คุณรู้ว่าทำไมมันถึงไม่ได้ผลสำหรับคุณ ลงคะแนนโดยไม่มีคำอธิบาย OTOH ไม่เป็นประโยชน์สำหรับทุกคนและมันก็ขี้ขลาด
Michael Scheper

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

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

2
คำถามคือโดยเฉพาะเกี่ยวกับชั้นเรียนเสื้อคลุม คำตอบนี้เป็นเรื่องเกี่ยวกับดั้งเดิม
Michael Scheper


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

หนึ่งควรเพิ่มว่ามันทำงานร่วมกับ autoboxing

มิฉะนั้นคุณจะได้รับ int (ดั้งเดิม) จากนั้นก็สามารถรับจำนวนเต็มได้:

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

2
อย่าใช้new Integer(int)แทนที่จะใช้Integer.valueOf(int)ซึ่งมีแคชสำหรับจำนวนเต็มขนาดเล็กเช่นอันนี้
bvdb


4

คุณสามารถทำได้โดยใช้ "การแปลงชนิดที่แคบหรือชัดเจน" double → long → int ฉันหวังว่ามันจะทำงาน

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

PS: มันจะให้ 0 เป็นสองเท่ามีค่าทศนิยมทั้งหมดและไม่มีอะไรอยู่ทางด้านซ้าย ในกรณีที่ 0.58 มันจะแคบลงเหลือ 0 แต่สำหรับคนอื่นมันจะใช้เวทย์มนตร์



3

Double และ Integer เป็นคลาส wrapper สำหรับ Java primitives สำหรับ double และ int ตามลำดับ คุณสามารถร่ายได้ระหว่างนั้น แต่คุณจะเสียจุดลอย นั่นคือ 5.4 การขว้างไปที่ int จะเป็น 5 หากคุณเหวี่ยงมันกลับไปจะเป็น 5.0


0

เพียงใช้วิธี intValue ของ Double

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

2
ดูเหมือนว่าจะซ้ำคำตอบอื่น ๆ
ปาง


-1

หน่วยความจำมีประสิทธิภาพเนื่องจากมันจะแบ่งปันอินสแตนซ์ที่สร้างไว้แล้วของ Double

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

มีเหตุผลMath.floor(...)อะไรบ้าง? intValue()ชั้นเสมอ
bvdb

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.