การทำงานกับจำนวนเต็ม
ในฐานะที่เป็นคลาส wrapper Integerจัดเตรียมวิธีการต่างๆ สำหรับการทำงานกับint ตลอดจนวิธีการต่างๆ ในการแปลงintเป็นStringและStringเป็นint คลาสนี้มีคอนสตรัคเตอร์สองตัว:-
public Integer(int i)โดยที่iเป็นค่าดั้งเดิมในการเริ่มต้น อันนี้สร้าง วัตถุ จำนวนเต็มที่เริ่มต้นด้วยค่าint
-
Public Integer(String s ) พ่นNumberFormatException นี่คือการแสดงสตริงของค่าint ตัวสร้างนี้สร้าง วัตถุ จำนวนเต็มที่เริ่มต้นด้วย ค่า intที่ให้มาโดยการเป็นตัวแทนสตริง
การสร้างวัตถุจำนวนเต็ม
มีตัวเลือกการสร้างวัตถุจำนวน เต็มที่แตกต่างกัน หนึ่งในวิธีที่ใช้กันมากที่สุดคือวิธีที่ง่ายที่สุด นี่คือตัวอย่าง:Integer myInteger = 5;
การกำหนดค่าเริ่มต้นของ ตัวแปร Integerในกรณีนี้จะคล้ายกับการกำหนดค่า เริ่มต้นของ ตัวแปร int ดั้งเดิม โดยวิธีการที่คุณสามารถเริ่มต้น ตัวแปร Integerด้วยค่าของint นี่คือตัวอย่าง:
int myInt = 5;
Integer myInteger = myInt;
System.out.println(myInteger);
ผลลัพธ์ที่นี่คือ:
Integer myInteger = new Integer(5);
คุณสามารถดำเนินการกับ ตัวแปร Integerได้เช่นเดียวกับint (บวก ลบ คูณ หาร เพิ่ม ลดค่า) อย่างไรก็ตาม สิ่งสำคัญคือต้องจำไว้ว่าIntegerเป็นประเภทข้อมูลอ้างอิง และตัวแปรประเภทนี้อาจเป็นค่าว่างได้ ในกรณีนี้ควรงดเว้นจากการดำเนินการดังกล่าวจะดีกว่า
Integer myInteger1 = null;
Integer myInteger2 = myInteger1 + 5;
ที่นี่เราจะได้รับข้อยกเว้น:
ค่าคงที่คลาสจำนวนเต็ม
คลาสIntegerจัดเตรียมค่าคงที่และวิธีการต่างๆ สำหรับการทำงานกับจำนวนเต็ม พวกเขาอยู่ที่นี่:-
SIZEหมายถึงจำนวนบิตในระบบตัวเลขสองหลักที่ถูกครอบครองโดยประเภทint
-
BYTESคือจำนวนไบต์ในระบบตัวเลขสองหลักที่ถูกครอบครองโดยประเภทint
-
MAX_VALUEคือค่าสูงสุดที่ ประเภท intสามารถเก็บได้
-
MIN_VALUEคือค่าต่ำสุดที่ ประเภท intสามารถเก็บได้
-
TYPEส่งคืนวัตถุประเภทClassจากประเภทint
วิธีที่มีประโยชน์ที่สุดคลาสจำนวนเต็ม
ตอนนี้เรามาดูวิธีการที่ใช้มากที่สุดของคลาสInteger กันดีกว่า ฉันคิดว่าที่นิยมมากที่สุดคือวิธีการแปลงตัวเลขจากStringหรือในทางกลับกัน-
int parseInt(String s) แบบคงที่วิธีการนี้จะแปลงStringเป็นint หากไม่สามารถแปลงได้NumberFormatExceptionจะถูกส่งออกไป
-
static int parseInt(String s , int radix)วิธีนี้ยังแปลง พารามิเตอร์ sเป็นint พารามิเตอร์Radixบ่งชี้ว่าระบบตัวเลขsถูกเขียนไว้ตั้งแต่แรก
-
static Integer valueOf(int i)ส่งคืนIntegerซึ่งมีค่าเป็นi ;
-
static Integer valueOf(String s)ทำงานเหมือนparseInt(String s)แต่ผลลัพธ์จะเป็นIntegerไม่ใช่int ;
-
static Integer valueOf(String s, int radix)ทำงานเหมือนกับparseInt(String s, int radix)แต่ผลลัพธ์คือIntegerไม่ใช่int
มีปัญหากับคลาส Integer หรือไม่? อ๋อ มี...
ดังนั้นจึงมีสองประเภทสำหรับจำนวนเต็ม (ที่พอดีกับ 32 บิต) ใน Java : intและInteger เพื่อให้เข้าใจถึงลักษณะเฉพาะของแต่ละรายการ เราจำเป็นต้องทราบข้อมูลต่อไปนี้เกี่ยวกับโมเดลหน่วยความจำ JVM: ทุกสิ่งที่คุณประกาศจะถูกเก็บไว้ใน Stack Memory (JVM Stack เฉพาะสำหรับแต่ละ Thread) หรือ Heap Space ประเภทดั้งเดิม ( int , long , float , boolean , double , char , byteฯลฯ ) จะถูกเก็บไว้ในหน่วยความจำ Stack ออบเจ็กต์และอาร์เรย์ทั้งหมดถูกจัดเก็บไว้ใน Heap Space การอ้างอิงถึงออบเจ็กต์และอาร์เรย์ที่จำเป็นสำหรับวิธีการเหล่านี้จะถูกจัดเก็บไว้ใน Stack ดังนั้น. ทำไมเราถึงสนใจ? คุณเห็นไหมว่า Stack มีขนาดเล็กกว่า Heap (a con) แต่จะจัดสรรค่าใน Stack ได้เร็วกว่า Heap (มืออาชีพ) มาก เริ่มต้นด้วยประเภทดั้งเดิมint มันกินพื้นที่ถึง 32 บิตพอดี นั่นคือ 32/8=4 ไบต์ เพราะมันเป็นประเภทดั้งเดิม ตอนนี้ลองพิจารณาInteger มันเป็นวัตถุที่มีค่าใช้จ่ายและการจัดแนวเพิ่มเติม ฉันใช้ไลบรารี jol เพื่อวัดขนาด:public static void main(String[] args) {
System.out.println(ClassLayout.parseInstance(Integer.valueOf(1)).toPrintable());
}
และปรากฎว่ามีขนาดถึง 16 ไบต์:
public static void main(String[] args) {
int[] array = new int[1000];
for (int i = 0; i < 1000; i++) array[i] = i; System.out.println(ClassLayout.parseInstance(array).toPrintable());
}
และผลลัพธ์คือ 4016 ไบต์:
public static void main(String[] args) {
List<Integer> list = new ArrayList<>(1000);
for (int i = 0; i < 1000; i++) list.add(i);
System.out.println(GraphLayout.parseInstance(list).toFootprint());
}
และผลลัพธ์คือ 20,040 ไบต์ (เพิ่มอีก 4 เท่า!):
public static void main(String[] args) {
TIntList list = new TIntArrayList(1000);
for (int i = 0; i < 1000; i++) list.add(i);
System.out.println(GraphLayout.parseInstance(list).toFootprint());
}
และผลลัพธ์คือ 4040 ไบต์ (เกือบจะเหมือนกับเพียงแค่int[] !):
benchmark {
configurations {
main {
warmups = 5 // number of warmup iterations
iterations = 50 // number of iterations
iterationTime = 500 // time in seconds per iteration
iterationTimeUnit = "ns" // time unit for iterationTime
เกณฑ์มาตรฐาน:
private static final Random random = new Random();
@Benchmark
public int testPrimitiveIntegersSum() {
int a = random.nextInt();
int b = random.nextInt();
return a + b;
}
@Benchmark
public Integer testBoxedIntegersSum() {
Integer a = random.nextInt();
Integer b = random.nextInt();
return a + b;
}
ผลลัพธ์:
@Benchmark
public int testPrimitiveArray() {
int[] array = new int[1000];
for (int i = 0; i < 1000; i++) array[i] = i;
int sum = 0;
for (int x : array) sum += x;
return sum;
}
11933.545 ops/s [Average]
@Benchmark
public int testBoxesArray() {
Integer[] array = new Integer[1000];
for (int i = 0; i < 1000; i++) array[i] = i;
int sum = 0;
for (int x : array) sum += x;
return sum;
}
2733.312 ops/s [Average]
@Benchmark
public int testList() {
List<Integer> list = new ArrayList<>(1000);
for (int i = 0; i < 1000; i++) list.add(i);
int sum = 0;
for (int x : list) sum += x;
return sum;
}
2086.379 ops/s [Average]
@Benchmark
public int testTroveIntList() {
TIntList list = new TIntArrayList(1000);
for (int i = 0; i < 1000; i++) list.add(i);
int sum = 0;
for (int i = 0; i < 1000; i++) sum += list.get(i);
return sum;
}
5727.979 ops/s [Average]
ผลลัพธ์: อาร์เรย์ดั้งเดิมเร็วกว่าอาร์เรย์ของค่าชนิดบรรจุกล่องมากกว่า 4 เท่า ( Integer s); เร็วกว่าArrayListของค่าชนิดบรรจุกล่องเกือบหกเท่า ( Integer s); และเร็วเป็นสองเท่าของTIntArrayList (ซึ่งจริง ๆ แล้วตกแต่งอาร์เรย์ของ ints ดั้งเดิม) ดังนั้น หากคุณต้องการโครงสร้างข้อมูลเพื่อจัดเก็บชุดของค่าจำนวนเต็ม และขนาดของมันจะไม่เปลี่ยนแปลง ให้ใช้int[] ; หากขนาดกำลังจะเปลี่ยนแปลง - คุณอาจต้องการใช้ไลบรารี tove4j กับTIntArrayList และนี่คือจุดสิ้นสุดของเรียงความของฉัน โดยที่ฉันอธิบายข้อเสียของการใช้ประเภทจำนวนเต็ม มีวิธีการคงที่ที่น่าสนใจของIntegerซึ่งฉันควรพูดถึงก่อนที่จะเสร็จสิ้น public static Integer getInteger(String nm, int val)ไม่ได้ทำในสิ่งที่เราคิด แต่ดึง ค่า Integerของคุณสมบัติระบบ Valเป็นค่าเริ่มต้นในกรณีที่ไม่ได้ตั้งค่าคุณสมบัตินี้ public static String toBinaryString(int i)ส่งคืนสตริงที่มีการแทนค่าไบนารี่ของตัวเลข มีวิธีการในการดึงข้อมูลการเป็นตัวแทน based-16 ( toHexString ) และ based-8 ( toOctalString ) มีวิธีแยกวิเคราะห์String ลงในint แม้ว่าสตริงจะเป็นการแสดงตามฐานที่ไม่ใช่ 10 นี่คือตัวอย่างบางส่วน: Integer.parseInt("-FF", 16)ส่งกลับ -255 Integer.parseInt("+42", 10)ส่งกลับ 42 Integer.parseInt("1100110", 2)ส่งกลับ 102
GO TO FULL VERSION