คำนำ
เมื่อคืนที่ผ่านมาฉันต้องการเพิ่ม Int ลงในตารางพจนานุกรมของสตริงในแอปพลิเคชัน Android Eclipse ประกาศเฉพาะวันนี้
ใช้ SparseArray ใหม่ <String> (... ) แทนเพื่อประสิทธิภาพที่ดีขึ้น
คำเตือนนี้หมายถึงการแทนที่โดยใช้ SparseArray เพื่อให้ได้ประสิทธิภาพที่ดีขึ้น
รหัสต้นฉบับ
เนื่องจากรหัสโดยรวมของ SparseArray นั้นค่อนข้างง่ายจึงแสดงซอร์สโค้ดก่อนแล้ววิเคราะห์ว่าทำไมใช้ SparseArray มีประสิทธิภาพที่ดีกว่าการใช้ HashMap
ระดับสาธารณะ sparsearray <e> ใช้ cloneable {วัตถุสุดท้ายคงที่ลบ = วัตถุใหม่ (); * * สร้าง SparseArray Conaining ใหม่ที่ไม่มีการแมปที่จะไม่ * ต้องการให้ใช้งานใด ๆ เพื่อหยุดการแมปที่ระบุ * หากคุณสนับสนุนความจุเริ่มต้นที่ 0 arlocations ที่ต้องการ = วัตถุใหม่ [initialCapacity];} msize = 0;}} @Override @SuppressWarnings ("ไม่ได้ตรวจสอบ") Public SparseArray <E> clone () {SparseArray <E> clone = NULL; ) super.clone (); * รับ Object MAPD จากคีย์สเปคหรือ < / null < / code> * หากไม่มีการแมปดังกล่าวที่ทำขึ้น รับวัตถุที่แมปจากคีย์ที่ระบุหรือวัตถุที่ระบุ * หากไม่มี ping ดังกล่าว , msize, key); ถ้า (i <0 || mvalues [i] == ted) {return valueifkeynotfound; คีย์ระบุหากมี ! ;} ** *ลบแผนที่ที่ดัชนีระบุ ;} / ** * ลบการแมปเป็นแบทช์ (msize, index+size); "SparseArray", GC เริ่มต้นด้วย "MSIZE; ) {ค่าวัตถุ = ค่า [i]; } o ++;}} mgarbage = false; มีหนึ่ง else {i = ~ i; mkeys.length) {gc (); msize + 1); int [] nkeys = new int [n]; ถึง " + n); system.arraycopy (mkeys, 0, nkeys, mkeys.length); system.arraycopy (mvalues, 0, nvalues, 0, mvalues.length); ys; mvalues = nvalues; -I -I! (mvalues, i, mvalues, i+1, msize -i);} mkeys [i] = key; / ขนาด int สาธารณะ () {gc ();} return msize;} / ** * ** * ที่ให้ไว้ใน Ange <code> 0 ... size () -1 </code>, ส่งคืน * คีย์จาก <code> ดัชนี </code> การแมปคีย์คีย์ที่จัดเก็บ * sparsearray นี้ คีย์และ <code> keyat (size () -1) </code> จะส่งคืนคีย์ larges * mkeys [index];}/** * ให้ดัชนีในช่วง <code> 0 ... size ()- 1 </code>, ส่งคืน * ค่าจาก <code> ดัชนี </code> คีย์- th- คีย์- การแมปค่าที่จัดเก็บ * SparseArray นี้ เชื่อมโยงกับ * คีย์ที่เล็กที่สุดและค่า (ขนาด () -1) </c ดัชนี) {ถ้า (mgarbage) {gc ();} return (e) es [index];} / * * * ให้ดัชนีในช่วง <code> 0 ... ขนาด () -1 </code>, ตั้งค่า * ค่าใหม่สำหรับ <code> ดัชนี </code> การแมปคีย์-ค่าที่ * Sparsearray st นี้ } mvalues [index] = value;} / ** * ส่งคืนดัชนีที่ {@link {@link #Keyat} จะส่งคืนปุ่ม * ที่ระบุหรือหมายเลขลบหากคีย์ * ที่ระบุไม่ได้แมป / public indexofkey (คีย์ int) {ถ้า (mgarbage) {gc ();} ส่งคืน c ontainerhelpers.binarySearch (mkeys, msize, key);} / *** ส่งคืนดัชนีที่ {@link #Valueat} * คีย์ที่ระบุหรือหมายเลขลบหากไม่มีคีย์แผนที่ไปยัง * ค่าที่ระบุ ค้นหาเพียงหนึ่งในนั้น if (mgarbage) {gc ();} สำหรับ (i <msize; i ++) ถ้า (mvalues [i] == ค่า) ส่งคืน i; จาก Sparsearray นี้ MSIZE = 0; if (msize! = 0 && k <= msize -1]) {ใส่ (คีย์, ค่า); ) {int n = arrayalintarraysize (pos + 1); int [] nkeys = new int [n]; mkeys.length + "ถึง" n); pos] = คีย์; mvalues [pos] = ค่า; มี itseel เป็นค่าแหวน st "(แผนที่นี้)" จะปรากฏในสถานที่ของมัน buffer = new StringBuilder (MSIZE * 28); } int key = keyat (i); อื่น {buffer.append ("(" ("(" end ('}'); return buffer.toString ();}}
ก่อนอื่นให้ดูที่ตัวสร้างของ Sparsearray:
/*** สร้าง SparseArray ใหม่ที่ไม่มีการแมป* /Public SparseArray () {this (10);} /*** สร้าง SparseArray ใหม่ไม่มีการแมปที่จะต้องใช้การจัดตำแหน่งหน่วยความจำเพิ่มเติมใด ๆ การแมป ;จะเห็นได้จากตัวสร้างว่าขนาดของคอนเทนเนอร์ถูกตั้งค่าล่วงหน้าและขนาดเริ่มต้นคือ 10
มาดูการดำเนินการเพิ่มข้อมูล:
/ ** * เพิ่มการแมปจากคีย์ที่ระบุไปยังค่าระบุ * การแก้ไขการแมปก่อนหน้านี้จากคีย์ที่ระบุหากมีหนึ่ง BinarySearch (mkeys, msize, key); ถ้า (i> = 0) {mvalues [i] = value;} else {i = ~ i; {mkeys [i] = key; , msize, msize, key);} if (msize> = mkeys.length) {int n = arrayutils.idealintarraysize (msize + 1); .e ("Sparsearray", "Grow" + mkeys.length + "ถึง" + n); mvalues = nvalues;} if (msize -i! = 0) {// log.e ("sparsearray", "move" + (msize -i)); 1, msize -i);
ดูวิธีการตรวจสอบข้อมูล:
/** * รับวัตถุที่แมปจากคีย์ระบุหรือ <code> null </code> * หากไม่มีการแมปดังกล่าว * รับวัตถุที่แมปจากคีย์ที่ระบุหรือวัตถุที่ระบุ * หากไม่มีการทำแผนที่ดังกล่าว ); ถ้า (i <0 || mvalues [i] == ลบ) {return valueifkeynotfound;} else {return (e) mvalues [i];}}
จะเห็นได้ว่าในกระบวนการของข้อมูลและรับข้อมูลอัลกอริทึมการค้นหาแบบคู่จะถูกเรียกอย่างสม่ำเสมอ
int binarySearch (int [] อาร์เรย์, ขนาด int, ค่า int) {int lO = 0; 1; ;} else {return mid; โดยส่วนตัวแล้วฉันคิดว่าวิธีการของ (lo + hi) >>> 1 ค่อนข้างแปลกและควรใช้ lo + (hi -lo) / 2 โดยตรง