jdk1.8.0_144 ดาวน์โหลดที่อยู่: //www.vevb.com/softs/551512.html
AbstractMap คลาสบทคัดย่อใช้วิธีการที่ง่ายและทั่วไปบางอย่างซึ่งไม่ยากในตัวเอง แต่มีสองวิธีในคลาสนามธรรมนี้ที่ควรค่าแก่การให้ความสนใจ การใช้รหัสแหล่งที่มาของวิธีการและค่าของค่านั้นสามารถกล่าวได้ว่าเป็นแบบจำลองสไตล์ตำราเรียน
คลาสบทคัดย่อมักจะถูกนำมาใช้เป็นโครงกระดูกเพื่อใช้วิธีการทั่วไปสำหรับคลาสย่อยที่เกี่ยวข้อง ในบทความก่อนหน้านี้เราอธิบายอินเทอร์เฟซแผนที่และบทความนี้วิเคราะห์และศึกษาคลาสนามธรรมนามธรรม
มีโครงสร้างข้อมูลประเภทแผนที่ค่อนข้างมากใน Java AbstractMap ในขณะที่การใช้โครงกระดูกของพวกเขาใช้วิธีการบางอย่างของอินเทอร์เฟซแผนที่นั่นคือมันให้วิธีการสาธารณะสำหรับคลาสย่อยและแผนที่ต่าง ๆ ที่ไม่มีการนำไปใช้อาจแตกต่างกัน
คลาสนามธรรมไม่สามารถสร้างอินสแตนซ์ของคลาสนามธรรมโดยตรงผ่านคำหลักใหม่ แต่สามารถมีตัวสร้างได้ AbstractMap ให้ตัวสร้างพารามิเตอร์ที่ได้รับการแก้ไขซึ่งหมายความว่ามีเพียงคลาสย่อยเท่านั้นที่สามารถเข้าถึงได้ (แน่นอนว่ามันเป็นคลาสนามธรรมและคลาสอื่น ๆ ไม่สามารถสร้างอินสแตนซ์โดยตรง) นั่นคือเฉพาะคลาสย่อยเท่านั้นที่สามารถเรียกตัวสร้างพารามิเตอร์นี้ได้
อินเทอร์เฟซรายการถูกกำหนดภายในในอินเทอร์เฟซแผนที่ อินเทอร์เฟซนี้เป็นการใช้งานภายในของแผนที่เพื่อรักษาคู่คีย์-ค่าคีย์และค่าคีย์จะถูกเก็บไว้ในแผนที่นี้ AbstractMap ใช้อินเทอร์เฟซภายในนี้มีสองอย่างทั้งหมด: หนึ่งคือสิ่งที่ไม่แน่นอนและอื่น ๆ คือส่วนที่ไม่เปลี่ยนรูปแบบง่าย
คลาสสแตติกสาธารณะ Simpleentry <k, v> ใช้รายการ <k, v>, java.io.serializable
อินเทอร์เฟซ Map.entry <k, V> ถูกนำไปใช้และ serializable (สามารถเป็นอนุกรม)
วิธีการของมันค่อนข้างง่ายซึ่งทั้งหมดเป็นการดำเนินการของการรับค่าและการจัดเก็บค่า คำจำกัดความของค่าคีย์คือการปรับเปลี่ยนขั้นสุดท้ายซึ่งหมายความว่าเป็นข้อมูลอ้างอิงที่ไม่เปลี่ยนรูป นอกจากนี้วิธีการ setValue นั้นพิเศษเล็กน้อย ค่าที่เก็บไว้ไม่ใช่ค่าที่เก็บไว้ แต่เป็นค่าเก่าที่ส่งคืน สิ่งที่คุณต้องเรียนรู้คือวิธีการเท่ากันและ hashcode ที่เขียนใหม่
บูลีนสาธารณะเท่ากับ (Object O) {ถ้า (! (o อินสแตนซ์ของ map.entry)) // เพื่อตรวจสอบว่าพารามิเตอร์เป็นของ map.entry ประเภทหรือไม่ถ้าเท่ากับเท่ากันสิ่งแรกที่ต้องทำคือการส่งคืนประเภทเดียวกัน; map.entry <?,?> e = (map.entry <?,?>) o; // บังคับให้ประเภทวัตถุเป็น map.entry ประเภทพารามิเตอร์ใช้ "?" แทนที่จะเป็น "k, v" เพราะประเภทของทั่วไปจะถูกลบในเวลารันไทม์ คอมไพเลอร์ไม่ทราบว่าประเภท K และ V คืออะไร, ส่งคืน eq (คีย์, e.getKey ()) && eq (ค่า, e.getValue ()); // คีย์และค่าโทรวิธี EQ สำหรับการตัดสินตามลำดับและเท่ากับเท่ากันเมื่อทั้งสองกลับมา - Boolean แบบคงที่ส่วนตัว EQ (Object O1, Object O2) {return o1 == null? O2 == null: o1.equals (O2); // ตัวดำเนินการสามรายการนี้ก็ง่ายมาก แต่ควรสังเกตว่าแม้ว่า O1 และ O2 เป็นประเภทวัตถุที่นี่วิธีการเท่ากับประเภทวัตถุถูกอ้างอิงโดย "==" ดังนั้นอย่าคิดว่ามีปัญหาที่นี่เพราะในความเป็นจริงประเภท O1 อาจเป็นสตริงแม้ว่ามันจะถูกเปลี่ยนเป็นวัตถุ -ในการเขียนวิธี Equals ใหม่อย่างถูกต้องและใช้อย่างถูกต้องคุณมักจะต้องเขียนวิธี HashCode ใหม่
public int hashCode () {return (key == null? 0: key.hashCode ()) ^ (value == null? 0: value.hashCode ()); // เมื่อค่าของคีย์และค่าไม่เป็นโมฆะ HashCode จะถูก xored -คลาสคงที่ระดับสาธารณะ SimpleImmutableentry <k, v> ใช้รายการ <k, v>, java.io.serializable simpleimmutableentry
รายการที่กำหนดว่าไม่เปลี่ยนรูปนั้นไม่เปลี่ยนรูปจริงเพราะมันไม่ได้ให้วิธี setValue และไม่สามารถแก้ไขได้ตามธรรมชาติผ่านวิธี setValue เมื่อมีการเข้าถึงเธรดหลายเธรดพร้อมกัน เมื่อเปรียบเทียบกับ SimpleEntry ตัวแปรสำคัญและค่าสมาชิกจะถูกกำหนดเป็นประเภทสุดท้าย การเรียกใช้วิธี setValue จะทำให้เกิดข้อยกเว้นที่ไม่ได้รับการยกเว้น
วิธีการเท่ากับและ hashcode นั้นสอดคล้องกับความเรียบง่าย
ถัดไปตรวจสอบว่าวิธีการใดในอินเทอร์เฟซแผนที่จะถูกนำไปใช้โดย AbstractMap Abstract Class
ขนาด int สาธารณะ ()
เมธอด entryset ถูกกำหนดไว้ในแผนที่ซึ่งส่งคืนชุดคอลเลกชันของ map.entry วิธีการขนาดของคอลเลกชันชุดเรียกโดยตรงซึ่งเป็นขนาดของแผนที่
บูลีนสาธารณะ isempty ()
โทรหาวิธีขนาดด้านบนเท่ากับ 0 มันว่างเปล่า
บูลีนสาธารณะมีคีย์ (คีย์วัตถุ)
การใช้วิธีนี้ค่อนข้างง่าย โดยการเรียกใช้วิธี entryset ตัววนซ้ำของคอลเลกชันชุดจะได้รับและข้ามด้วยคีย์พารามิเตอร์ แผนที่สามารถเก็บไว้เป็นค่าคีย์ของ Null เนื่องจากคีย์ = null ถูกเก็บไว้ในแผนที่พร้อมที่เก็บข้อมูลพิเศษพิเศษ (ไม่สามารถคำนวณค่า hashcode) เราจึงได้ทำวิธีในการตรวจสอบว่าคีย์พารามิเตอร์ว่างเปล่าหรือไม่
บูลีนสาธารณะมีค่า (ค่าวัตถุ)
การใช้วิธีนี้สอดคล้องกับ ContainsKey
สาธารณะ v รับ (คีย์วัตถุ)
การใช้วิธีนี้คล้ายกับสองข้างต้นความแตกต่างคือข้างต้นเท่ากับบูลีนและวิธีนี้จะส่งคืนค่า
Public V Put (k key, v value)
วิธีการจัดเก็บคู่ค่าคีย์ลงในแผนที่ไม่ได้ถูกนำมาใช้ในรายละเอียดและจะถูกโยนลงไปโดยตรง
Public V ลบ (คีย์วัตถุ)
ลบคู่คีย์ค่าคีย์-ค่าที่ระบุไว้ในแผนที่ผ่านปุ่มพารามิเตอร์ วิธีนี้ก็ง่ายมาก นอกจากนี้ยังสำรวจชุดคอลเลกชันของ Map.entry ผ่านตัววนซ้ำค้นหาค่าคีย์ที่สอดคล้องกันและลบ map.entry โดยเรียกใช้วิธี iterator#ลบ
Public Void Putall (MAP <? ขยาย k,? ขยาย v> m)
วิธีนี้ยังง่ายมากที่จะสำรวจแผนที่ขาเข้าและเพียงแค่เรียกใช้วิธีการที่จะบันทึก
ช่องว่างสาธารณะชัดเจน ()
โทรหาวิธี entryset เพื่อรับคอลเลกชันชุดจากนั้นเรียกใช้เมธอด Set#Clear () เพื่อล้าง
ชุดสาธารณะ <k> keyset ()
ส่งคืนชุดคอลเลกชันของค่าคีย์แผนที่ AbstractMap กำหนดตัวแปรสมาชิก "ชุดปุ่มชั่วคราว <k> keyset" ใน JDK7 ตัวแปรคีย์จะถูกแก้ไขโดยความผันผวน แต่ใน JDK8 มันไม่ได้ถูกแก้ไขโดยผันผวน มีการอธิบายไว้ในความคิดเห็นเกี่ยวกับตัวแปรคีย์เซ็ตว่าวิธีการเข้าถึงฟิลด์เหล่านี้ไม่ได้ซิงโครไนซ์ด้วยตัวเองและความผันผวนไม่สามารถรับประกันความปลอดภัยของเธรดได้ การใช้วิธีคีย์เซ็ตนั้นน่าสนใจ
ก่อนอื่นลองคิดดูเกี่ยวกับวิธีนี้คือการส่งคืนชุดชุดของค่าคีย์ โดยธรรมชาติเราสามารถนึกถึงวิธีการใช้งานง่าย ๆ สำรวจอาร์เรย์รายการและนำค่าคีย์ออกมาและใส่ไว้ในชุดที่ตั้งคล้ายกับรหัสต่อไปนี้:
ชุดสาธารณะ <k> keyset () {set <k> ks = null; สำหรับ (map.entry <k, v> รายการ: entryset ()) {ks.add (entry.getKey ()); } return ks;}ซึ่งหมายความว่าทุกครั้งที่มีการเรียกวิธีการตั้งค่าคีย์มันจะสำรวจอาร์เรย์รายการและประสิทธิภาพจะลดลงอย่างมากเมื่อปริมาณข้อมูลมีขนาดใหญ่ ฉันต้องบอกว่าซอร์สโค้ด JDK เขียนได้ดีมากและไม่ได้ใช้วิธีการสำรวจ หากคุณไม่ข้ามรายการคุณจะรู้ได้อย่างไรว่าแผนที่ได้เพิ่มคู่คีย์-ค่าคู่คีย์ในเวลานี้?
คำตอบคือการตรวจสอบคอลเลกชันชุดที่กำหนดเองใหม่ใหม่ภายในวิธีการคีย์เซ็ตและเมธอดตัววนซ้ำจะถูกเขียนใหม่ในคอลเลกชันชุดที่กำหนดเองนี้ นี่คือกุญแจสำคัญ เมธอดตัววนซ้ำจะส่งคืนอินเทอร์เฟซของตัววนซ้ำและที่นี่จะมีการดำเนินการอีกครั้ง โดยการเรียกวิธีการ entryset แล้วเรียกใช้วิธีการวนซ้ำ ต่อไปนี้ได้รับการวิเคราะห์ร่วมกับรหัส:
ชุดสาธารณะ <k> keyset () {set <k> ks = keyset; // กำหนดค่าชั่วคราว <k> keyset ถ้า (ks == null) {// การโทรครั้งแรกนั้นเป็นโมฆะแน่นอนสร้างตัวอย่างชุดผ่านรหัสต่อไปนี้ ks = new Abstractset <k> () {// สร้างชุด ITERATOR Public Iterator ตัววนซ้ำ <entry <k, v >> i = entrySet (). iterator (); // สร้างชุดคอลเลกชันตัววนซ้ำบูลีนสาธารณะ hasnext () {return i.hasnext (); // คำพิพากษาของค่าคีย์คือการตัดสินของรายการ} สาธารณะ k next () {return i.next (). getKey (); // ค่าคีย์ถัดไปคือการเข้าร่วม#getKey} โมฆะสาธารณะลบ () {i.remove (); // ลบค่าคีย์ลบรายการ}}; } ขนาด int สาธารณะ () {// ชุดที่เขียนขึ้นใหม่เมธอดส่งคืน AbstractMap.this.size (); // ค่าของคีย์คือแผนที่ทั้งหมดขนาดใหญ่เพียงใดดังนั้นเพียงโทรหาวิธีขนาดของคลาสนี้ นี่คือคลาสภายใน ใช้คำหลักนี้เพื่อแสดงคลาสนี้โดยตรง ควรระบุว่าวิธีการขนาดใน AbstractMap เรียกว่า หากไม่มีสิ่งนี้หมายความว่ามันเป็นวิธีการคงที่} บูลีนสาธารณะ isempty () {// ชุดที่เขียนใหม่#isempty วิธีการส่งคืน abstractmap.his.isempty (); // สำหรับว่ามีค่าคีย์หมายความว่าแผนที่ว่างเปล่าหรือไม่ดังนั้นจึงเป็นเพียงการเรียกวิธีการ isempty ของคลาสนี้} โมฆะสาธารณะ Clear () {// ชุดที่เขียนใหม่#Clear Method AbstractMap.this.clear (); // ล้างค่าคีย์มันเป็นเพียงการล้างแผนที่ดังนั้นจึงเป็นเพียงการเรียกวิธีการที่ชัดเจนของคลาสนี้} บูลีนสาธารณะประกอบด้วย (วัตถุ K) {// rewrite set#มีวิธีการส่งคืน AbstractMap.this.containskey (k); // ตัดสินว่าชุดมีข้อมูล K ซึ่งหมายความว่าแผนที่มีค่าคีย์หรือไม่ดังนั้นเพียงเรียกใช้วิธีการของคีย์ของคลาสนี้}}; keyset = ks; // กำหนดคอลเลกชันชุดที่กำหนดเองนี้ให้กับคีย์คีย์ตัวแปร เมื่อเรียกใช้วิธีการคีย์อีกครั้งในอนาคตเนื่องจากคีย์ไม่ได้เป็นโมฆะคุณเพียงแค่ต้องกลับมาโดยตรง } return ks;ฉันคิดว่านี่เป็นการใช้งานที่ฉลาดมาก แม้ว่าวิธีนี้จะหมุนรอบค่าคีย์ แต่ก็สามารถนำไปใช้ร่วมกับรายการได้โดยไม่ต้องข้ามรายการ ในขณะเดียวกันก็มีการกล่าวถึงข้างต้นว่าการเรียกใช้วิธี entryset# iterator ซึ่งเป็นวิธีปฏิบัติที่ดีที่สุดของโหมดวิธีการเทมเพลต เนื่องจากชุดรายการไม่ได้ถูกนำไปใช้ใน AbstractMap แต่ถูกทิ้งให้อยู่ในคลาสย่อยเพื่อให้เสร็จสมบูรณ์ แต่วิธีการคีย์เซ็ตสามารถนำไปใช้กับ "Skeleton อัลกอริทึม" ซึ่งเป็นรูปแบบวิธีการเทมเพลต
การรวบรวมสาธารณะ <v> ค่า ()
สำหรับวิธีการค่าคุณสามารถอ้างถึงคีย์เซ็ตได้อย่างสมบูรณ์ ทั้งสองมีเอฟเฟกต์เดียวกันดังนั้นฉันจะไม่ทำซ้ำที่นี่เพื่อประหยัดพื้นที่
ชุดนามธรรมสาธารณะ <รายการ <k, v >> entryset ()
วิธีนามธรรมถูกส่งมอบให้กับคลาสย่อยเพื่อให้เสร็จสมบูรณ์ซึ่งบ่งชี้ว่าวิธีนี้ไม่ได้เป็น "ทั่วไป" โดยเฉพาะ
บูลีนสาธารณะเท่ากับ (Object O)
แผนที่กำหนดว่าเฉพาะเมื่อคีย์และค่าของคู่คีย์-ค่าแต่ละคู่ในแผนที่สอดคล้องกันโดยหนึ่งจะส่งคืนจริง ในวิธีการก่อนตัดสินเงื่อนไขง่าย ๆ หากการอ้างอิงเท่ากันให้ส่งคืนจริงโดยตรง หากพารามิเตอร์ O ไม่ใช่ประเภทแผนที่ให้ส่งคืนเท็จโดยตรง หากจำนวนแผนที่ทั้งสองนั้นแตกต่างกันให้ส่งคืนเท็จโดยตรง จากนั้นจะวนซ้ำผ่านอาร์เรย์รายการและเปรียบเทียบว่าคีย์และค่าในรายการนั้นสอดคล้องกันโดยหนึ่งหรือไม่ วิธีนี้ง่าย แต่สิ่งนี้ทำให้เรามีแรงบันดาลใจ ในการตัดสินตามเงื่อนไขเราควรตัดสินขั้นตอนพื้นฐานง่ายๆก่อนจากนั้นตัดสินคนที่ซับซ้อน
hashcode int สาธารณะ ()
เขียนวิธี Equals ของคลาส Object ใหม่อีกครั้งและจำเป็นต้องเขียน HashCode อีกครั้งเช่นกัน การใช้ HashCode ของ AbstractMap คือการเพิ่มค่า hashcode ของ map.entry ทั้งหมด (นี่คือ SimpleIntry หรือ Simpleimmutableentry) ลงไปที่จุดสิ้นสุดและผลรวมสุดท้ายจะใช้เป็นค่า hashcode ของแผนที่
สตริงสาธารณะ toString ()
ไม่มีอะไรจะพูดเกี่ยวกับวิธีนี้มันคือการเอาคู่คีย์-ค่าทั้งหมดออกมาและใช้ Stringbuilder เพื่อแยกพวกเขา
object clone () phrows clonenotsupportedexception
ใช้สำเนาตื้นเพราะมันเป็นสำเนาของคีย์และค่าตัวแปรตื้นและการป้องกันปัญหาที่เกิดจากสำเนาตื้นทั้งสอง