ในบทช่วยสอนสั้นๆ นี้ คุณจะได้เรียนรู้วิธีกลับรายการแบบแทนที่รายการแทนที่ใน Java
การย้อนกลับในสถานที่และนอกสถานที่
เมื่อดำเนินการกับรายการ – คุณอาจต้องการพิจารณาว่าการดำเนินการนั้นเสร็จสิ้นแล้วหรือไม่ (การเปลี่ยนแปลงมีผลกับวัตถุดั้งเดิม) หรือว่าไม่อยู่ในตำแหน่ง (การเปลี่ยนแปลงมีผลกับสำเนาและต้นฉบับ วัตถุไม่เปลี่ยนแปลง)
บางภาษาและไลบรารีต้องการพฤติกรรมเริ่มต้นที่แตกต่างกัน ใน Java การดำเนินการส่วนใหญ่ในรายการย้อนกลับจะเป็น ในสถานที่.
หากนี่เป็นพฤติกรรมที่คุณต้องการ – เยี่ยมมาก! ถ้าไม่เช่นนั้น คุณจะต้องสร้างสำเนาของรายการก่อนที่จะย้อนกลับสำเนา:
List list = new ArrayList(Arrays.asList(1, 2, 3));
List listCopy = new ArrayList(list);
หมายเหตุ พื้นที่ clone()
วิธี ไม่ได้ สร้างสำเนาลึก การสร้างรายการโดยใช้ new ArrayList(list)
ไม่ได้ สร้างสำเนาลึก การสร้างสำเนาในเชิงลึกเป็นสิ่งที่ไม่ควรทำ และทำได้ยากอย่างน่าประหลาดใจในลักษณะทั่วไป (และไม่สมเหตุสมผลในบางกรณี ขึ้นอยู่กับประเภทข้อมูลในรายการ) สิ่งนี้จะไม่หยุดคุณไม่สามารถย้อนกลับได้ list
และ ไม่ มีองค์ประกอบของ listCopy
ถูกย้อนกลับแม้ว่า
คอลเลกชันย้อนกลับ ()
พื้นที่ Collections.reverse()
วิธีเป็นวิธีมาตรฐานในการย้อนกลับของคอลเลกชันและทำหน้าที่เป็น "หายไป" List.reverse()
กระบวนการ. มันกลับรายการในสถานที่:
List list = new ArrayList(Arrays.asList(1, 2, 3));
List listCopy = new ArrayList(list);
Collections.reverse(list);
System.out.println(list);
System.out.println(listCopy);
รายการฝรั่ง.ย้อนกลับ(รายการ)
หากคุณใช้ Google Guava ในโครงการอยู่แล้ว คุณยังสามารถใช้ประโยชน์จาก Lists
คลาสซึ่งให้ reverse()
เมธอด ซึ่งไม่เรียงลำดับรายการดั้งเดิมแบบแทนที่ แต่สร้างสำเนาและย้อนกลับสำเนา:
List list = new ArrayList(Arrays.asList(1, 2, 3));
List reversedList = Lists.reverse(list);
System.out.println(list);
System.out.println(reversedList);
หากคุณยังไม่มี คุณสามารถเพิ่ม Google Guava ในโครงการของคุณโดยใช้ Maven โดยรวมการพึ่งพาใน pom.xml
ไฟล์:
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
หรือผ่าน Gradle:
implementation group: 'com.google.guava', name: 'guava'
หมายเหตุ หากคุณยังไม่มี Google Guava หรือไม่ต้องการใช้สำหรับส่วนอื่นๆ ของโปรเจ็กต์ของคุณ อย่านำเข้ามาเพื่อการดำเนินการนี้เพียงอย่างเดียว และยึดตาม Collections.reverse()
กระบวนการ. ฝรั่งเป็นที่พึ่งพาอาศัยกันมาก และเป็นการ overkill ที่สำคัญสำหรับการดำเนินการนี้เท่านั้น
List.add() และ List.remove()
หากคุณต้องการดำเนินการเพิ่มเติมนอกเหนือจากการย้อนกลับรายการ คุณสามารถทำซ้ำผ่านรายการเดิม ลบองค์ประกอบออกจากจุดสิ้นสุด ส่งผ่านวิธีการใดก็ได้ และเพิ่มกลับเข้าไปที่จุดเริ่มต้นของรายการ:
public static int process(int input) {
return input;
}
List list = new ArrayList(Arrays.asList(1, 2, 3));
for (int i = 0, j = list.size()-1; i <= j; i++) {
int lastValue = process(list.remove(j));
list.add(i, lastValue);
}
System.out.println(list);
มาตรฐาน
แล้วอันไหนเร็วที่สุด? นอกจากนี้ยังขึ้นอยู่กับว่าคุณต้องการดำเนินการในสถานที่หรือนอกสถานที่
เกณฑ์มาตรฐานการกลับรายการในสถานที่
มาเปรียบเทียบทั้งสองแนวทางกับทั้งสามวิธีกัน โดยเริ่มจากนอกสถานที่:
List list = new Random().ints(100, 1, 11)
.boxed()
.collect(Collectors.toList());
int runs = 1000;
long start1 = System.currentTimeMillis();
for (int i = 0; i < runs; i++) {
reverseListCollections(list);
}
long end1 = System.currentTimeMillis();
System.out.println(String.format("Collections.reverse() took: %s miliseconds", end1-start1));
long start2 = System.currentTimeMillis();
for (int i = 0; i < runs; i++) {
reverseListGuava(list);
}
long end2 = System.currentTimeMillis();
System.out.println(String.format("Guava's Lists.reverse() took: %s miliseconds", end2-start2));
long start3 = System.currentTimeMillis();
for (int i = 0; i < runs; i++) {
reverseListManually(list);
}
long end3 = System.currentTimeMillis();
System.out.println(String.format("Manually took: %s miliseconds", end3-start3));
System.out.println("Original list: " + list);
ผลลัพธ์นี้ใน:
Collections.reverse() took: 3 miliseconds
Guava's Lists.reverse() took: 4 miliseconds
Manually took: 13 miliseconds
Original list: [6, 7, 9, 7, 2, 5, 4, 1, 3, 2, 2, 6, ...
ดูคู่มือเชิงปฏิบัติสำหรับการเรียนรู้ Git ที่มีแนวทางปฏิบัติที่ดีที่สุด มาตรฐานที่ยอมรับในอุตสาหกรรม และเอกสารสรุปรวม หยุดคำสั่ง Googling Git และจริงๆ แล้ว เรียน มัน!
จะเกิดอะไรขึ้นเมื่อเราเพิ่มจำนวนองค์ประกอบจาก 100 เป็น 1000
Collections.reverse() took: 9 miliseconds
Guava's Lists.reverse() took: 4 miliseconds
Manually took: 133 miliseconds
Original list: [10, 2, 2, 6, 2, 4, 7, 3, 9, 2, 7, 5, ...
ฝรั่งยังคงเครื่องหมาย 4ms! วิธีการแบบแมนนวลมีความซับซ้อนด้านเวลาที่เลวร้ายที่สุด และเพิ่มขึ้นเป็นเส้นตรง Collections.reverse()
ทนทุกข์ทรมานน้อยลงจากการขยายขนาด แต่การนำของฝรั่งไปปฏิบัติได้รับความทุกข์น้อยที่สุด แม้ว่า โปรดจำไว้ว่า เราไม่ได้คัดลอกรายการสำหรับแนวทางฝรั่งด้วยตนเอง เกณฑ์มาตรฐานจะเปลี่ยนไปเมื่อเราละทิ้งแนวคิดที่จะมีรายการ "ดั้งเดิม" และ "ย้อนกลับ" หรือไม่
เกณฑ์มาตรฐานการกลับรายการนอกสถานที่
ด้วยองค์ประกอบ 1000 รายการและแต่ละรายการทำงานบนสำเนารายการที่ไม่ย้อนกลับ (ซึ่งไม่รวมอยู่ในการวัดเวลา) เมื่อเราลบสำเนาด้วยตนเองออกจากแต่ละวิธีและเรียกใช้รหัสอีกครั้ง:
Collections.reverse() took: 7 miliseconds
Guava's Lists.reverse() took: 3 miliseconds
Manually took: 131 miliseconds
Original list: [6, 8, 10, 7, 3, 8, 7, 1, 1, 9, 5, ...
ฝรั่ง ยังคง มีประสิทธิภาพเหนือกว่าทั้งคู่อย่างต่อเนื่อง Collections.reverse()
และแนวทางแบบแมนนวล
สรุป
ในคู่มือฉบับย่อนี้ คุณได้เรียนรู้วิธีย้อนกลับรายการใน Java ทั้งแบบแทนที่และไม่อยู่ในตำแหน่ง เพื่อรักษารายการเดิมไว้ไม่ให้ทำงาน เราใช้ Collections.reverse()
วิธีการ, Google Guava's Lists.reverse()
วิธีการและแนวทางด้วยตนเอง