ดูJavaDocsและคำพูดนี้โดย Stuart Marks (หรือเวอร์ชันก่อนหน้า)
ฉันจะใช้สิ่งต่อไปนี้สำหรับตัวอย่างโค้ด:
List<Integer> listOf = List.of(...);
List<Integer> asList = Arrays.asList(...);
List<Integer> unmodif = Collections.unmodifiableList(asList);
ความไม่เปลี่ยนรูปของโครงสร้าง (หรือ: unmodifiability)
ความพยายามใด ๆ ในการเปลี่ยนแปลงเชิงโครงสร้างList.of
จะส่งผลให้UnsupportedOperationException
ไฟล์. ซึ่งรวมถึงการดำเนินการเช่นการเพิ่ม , ชุดและลบ อย่างไรก็ตามคุณสามารถเปลี่ยนเนื้อหาของวัตถุในรายการได้ (หากวัตถุไม่เปลี่ยนรูป) ดังนั้นรายการจึงไม่ "ไม่เปลี่ยนรูปโดยสิ้นเชิง"
นี่คือชะตากรรมเดียวกันสำหรับรายการ unmodifiable Collections.unmodifiableList
สร้างขึ้นด้วย รายการนี้เท่านั้นที่เป็นมุมมองของรายการต้นฉบับดังนั้นจึงสามารถเปลี่ยนแปลงได้หากคุณเปลี่ยนรายการเดิม
Arrays.asList
ไม่ได้เปลี่ยนรูปสมบูรณ์ก็ไม่ได้มีข้อ จำกัด set
ในการ
listOf.set(1, "a"); // UnsupportedOperationException
unmodif.set(1, "a"); // UnsupportedOperationException
asList.set(1, "a"); // modified unmodif! unmodif is not truly unmodifiable
ในทำนองเดียวกันการเปลี่ยนอาร์เรย์สำรอง (ถ้าคุณถือไว้) จะเปลี่ยนรายการ
ความไม่เปลี่ยนรูปของโครงสร้างมาพร้อมกับผลข้างเคียงมากมายที่เกี่ยวข้องกับการเข้ารหัสป้องกันภาวะพร้อมกันและความปลอดภัยซึ่งอยู่นอกเหนือขอบเขตของคำตอบนี้
ความเป็นศัตรูที่เป็นโมฆะ
List.of
และคอลเลกชันใด ๆ ตั้งแต่ Java 1.5 ไม่อนุญาตให้null
เป็นองค์ประกอบ การพยายามส่งผ่านnull
เป็นองค์ประกอบหรือแม้แต่การค้นหาจะส่งผลให้ไฟล์NullPointerException
.
เนื่องจากArrays.asList
เป็นคอลเล็กชันจาก 1.2 (Collections Framework) จึงอนุญาตให้null
s
listOf.contains(null); // NullPointerException
unmodif.contains(null); // allowed
asList.contains(null); // allowed
แบบฟอร์มต่อเนื่อง
เนื่องจากList.of
ได้รับการแนะนำใน Java 9 และรายการที่สร้างโดยวิธีนี้มีรูปแบบอนุกรม (ไบนารี) เป็นของตัวเองจึงไม่สามารถ deserialized ใน JDK เวอร์ชันก่อนหน้านี้ได้ (ไม่มีความเข้ากันได้แบบไบนารี ) อย่างไรก็ตามคุณสามารถ de / serialize ด้วย JSON ได้เช่น
เอกลักษณ์
Arrays.asList
การโทรภายในnew ArrayList
ซึ่งรับประกันความไม่เท่าเทียมกันในการอ้างอิง
List.of
ขึ้นอยู่กับการใช้งานภายใน อินสแตนซ์ที่ส่งคืนอาจมีความเท่าเทียมกันในการอ้างอิง แต่เนื่องจากไม่รับประกันว่าคุณไม่สามารถวางใจได้
asList1 == asList2; // false
listOf1 == listOf2; // true or false
ควรค่าแก่การกล่าวถึงว่ารายการมีค่าเท่ากัน (ผ่านList.equals
) หากมีองค์ประกอบเดียวกันในลำดับเดียวกันไม่ว่าจะสร้างขึ้นอย่างไรหรือสนับสนุนการดำเนินการใดก็ตาม
asList.equals(listOf); // true i.f.f. same elements in same order
การใช้งาน (คำเตือน: รายละเอียดสามารถเปลี่ยนแปลงได้ในหลายเวอร์ชัน)
หากจำนวนองค์ประกอบในรายการList.of
2 หรือน้อยกว่าองค์ประกอบจะถูกเก็บไว้ในฟิลด์ของคลาสพิเศษ (ภายใน) ตัวอย่างคือรายการที่เก็บ 2 องค์ประกอบ (ที่มาบางส่วน):
static final class List2<E> extends AbstractImmutableList<E> {
private final E e0;
private final E e1;
List2(E e0, E e1) {
this.e0 = Objects.requireNonNull(e0);
this.e1 = Objects.requireNonNull(e1);
}
}
Arrays.asList
มิฉะนั้นพวกเขาจะถูกเก็บไว้ในอาร์เรย์ในลักษณะคล้ายกับ
ประสิทธิภาพของเวลาและพื้นที่
การList.of
ใช้งานที่อิงตามภาคสนาม (ขนาด <2) จะทำงานได้เร็วขึ้นเล็กน้อยในการดำเนินการบางอย่าง ดังตัวอย่างsize()
สามารถส่งคืนค่าคงที่โดยไม่ต้องดึงความยาวอาร์เรย์และcontains(E e)
ไม่จำเป็นต้องมีค่าใช้จ่ายในการวนซ้ำ
การสร้างรายการที่ไม่สามารถแก้ไขได้ผ่านทางList.of
นั้นเร็วกว่าด้วย เปรียบเทียบตัวสร้างข้างต้นกับการกำหนดอ้างอิง 2 รายการ (และแม้แต่ตัวสร้างสำหรับจำนวนองค์ประกอบโดยพลการ) กับ
Collections.unmodifiableList(Arrays.asList(...));
ซึ่งสร้าง 2 รายการพร้อมค่าใช้จ่ายอื่น ๆ ในแง่ของพื้นที่คุณสามารถประหยัดUnmodifiableList
กระดาษห่อหุ้มและเหรียญเพนนี ท้ายที่สุดแล้วการประหยัดที่HashSet
เทียบเท่านั้นน่าเชื่อกว่า
เวลาสรุป: ใช้List.of
เมื่อคุณต้องการรายการที่ไม่เปลี่ยนแปลงและArrays.asList
เมื่อคุณต้องการรายการที่สามารถเปลี่ยนแปลงได้ (ดังแสดงด้านบน)