JavaRush /จาวาบล็อก /Random-TH /คลาส ArrayList ใน Java

คลาส ArrayList ใน Java

เผยแพร่ในกลุ่ม
สวัสดี! ในการบรรยายครั้งก่อน เราได้ตรวจสอบรายละเอียดเช่นโครงสร้างข้อมูลเป็นอาร์เรย์ และดูตัวอย่างทั่วไปของการทำงานร่วมกับโครงสร้างเหล่านั้น แต่โครงสร้างข้อมูลนี้มีข้อเสียหลายประการ คำตอบสำหรับพวกเขาใน Java คือรูปลักษณ์ของ ArrayList เพื่อให้ง่ายที่สุดเท่าที่จะเป็นไปได้ ArrayList ใน Java นั้นเป็นอาร์เรย์ "อัปเกรด" พร้อมคุณสมบัติใหม่มากมายคลาสอาร์เรย์รายการ - 1

Java Arraylist แตกต่างจากอาร์เรย์ทั่วไปอย่างไร

โดยทั่วไปอาร์เรย์ค่อนข้างสะดวกและตามที่คุณสังเกตเห็นแล้วคุณสามารถทำสิ่งต่างๆ ได้มากมาย :) อย่างไรก็ตาม อาร์เรย์ก็มีข้อเสียหลายประการเช่นกัน
  • ขนาดจำกัด. คุณจำเป็นต้องรู้อยู่แล้วในขั้นตอนของการสร้างอาร์เรย์ว่าควรมีเซลล์จำนวนเท่าใด หากประเมินจำนวนเงินที่ต้องการต่ำไปก็จะมีพื้นที่ไม่เพียงพอ หากคุณประเมินค่าสูงไป อาร์เรย์จะยังคงว่างเปล่าครึ่งหนึ่ง และนั่นก็ไม่ได้แย่นัก ท้ายที่สุดปรากฎว่าคุณจะจัดสรรหน่วยความจำให้เกินความจำเป็นด้วย
  • อาร์เรย์ไม่มีวิธีการเพิ่มองค์ประกอบ คุณต้องระบุดัชนีของเซลล์ที่คุณต้องการเพิ่มองค์ประกอบให้ชัดเจนเสมอ หากคุณระบุเซลล์ที่ถูกครอบครองแล้วด้วยค่าที่ต้องการโดยไม่ได้ตั้งใจ เซลล์นั้นจะถูกเขียนทับ
  • ไม่มีวิธีการลบองค์ประกอบ ค่าสามารถเป็น "ศูนย์" เท่านั้น
public class Cat {

   private String name;

   public Cat(String name) {
       this.name = name;
   }

   public static void main(String[] args) {

       Cat[] cats = new Cat[3];
       cats[0] = new Cat("Thomas");
       cats[1] = new Cat("Hippopotamus");
       cats[2] = new Cat("Philip Markovich");

       cats[1] = null;



       System.out.println(Arrays.toString(cats));
   }

   @Override
   public String toString() {
       return "Cat{" +
               "name='" + name + '\'' +
               '}';
   }
}
บทสรุป:

[Cat{name='Томас'}, null, Cat{name='Фorпп Маркович'}]
ข้อบกพร่องทั้งหมดนี้สามารถกำจัดได้โดยใช้ ArrayList มันถูกสร้างขึ้นอย่างเรียบง่าย:
ArrayList<Cat> cats = new ArrayList<Cat>();
ตอนนี้เราได้สร้างรายการเพื่อจัดเก็บวัตถุCatแล้ว ใส่ใจ:เราไม่ได้ระบุขนาดของ ArrayList เนื่องจากสามารถขยายได้โดยอัตโนมัติ สิ่งนี้เป็นไปได้อย่างไร? อย่างง่ายดาย. คุณจะต้องแปลกใจ แต่ ArrayList ใช้อาร์เรย์ธรรมดา :) ใช่แล้ว ข้างในนั้นมีอาร์เรย์ที่องค์ประกอบของเราถูกเก็บไว้ แต่ ArrayList มีกลไกพิเศษในการทำงานกับมัน:
  • เมื่ออาร์เรย์ภายในนี้เต็ม ArrayList จะสร้างอาร์เรย์ใหม่ภายในตัวมันเอง ขนาดของมัน = (ขนาดของอาเรย์เก่า * 1.5) +1
  • ข้อมูลทั้งหมดจะถูกคัดลอกจากอาเรย์เก่าไปยังอาเรย์ใหม่
  • อาร์เรย์เก่าจะถูกลบออกโดยตัวรวบรวมขยะ
ด้วยกลไกนี้ ArrayList (ซึ่งตรงข้ามกับอาร์เรย์) ใช้วิธีการเพิ่มองค์ประกอบใหม่ นี่เป็นวิธีadd()การ
public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<Cat>();
   cats.add(new Cat("Hippopotamus"));
}
องค์ประกอบใหม่จะถูกเพิ่มไปที่ส่วนท้ายของรายการ ขณะนี้ไม่มีความเสี่ยงที่จะล้น ดังนั้นกลไกนี้จึงปลอดภัยอย่างสมบูรณ์ อย่างไรก็ตาม ArrayList ไม่เพียงแต่สามารถค้นหาวัตถุตามดัชนีเท่านั้น แต่ยังสามารถค้นหาดัชนีของวัตถุใน ArrayList ได้โดยการอ้างอิงถึงวัตถุนั้นด้วย! ในการดำเนินการนี้จะใช้วิธีindexOf(): เราส่งลิงก์ไปยังวัตถุที่ต้องการและindexOf()ส่งคืนดัชนีให้เรา:
public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();
   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Hippopotamus");
   Cat philipp = new Cat("Philip Markovich");
   Cat pushok = new Cat("Fluff");

   cats.add(thomas);
   cats.add(behemoth);
   cats.add(philipp);
   cats.add(pushok);

   int thomasIndex = cats.indexOf(thomas);
   System.out.println(thomasIndex);
}
บทสรุป:

0
ถูกต้องแล้ว วัตถุนั้นthomasถูกจัดเก็บไว้ในเซลล์0จริงๆ อาร์เรย์ไม่เพียงแต่มีข้อเสียเท่านั้น แต่ยังมีข้อดีอย่างไม่ต้องสงสัยอีกด้วย หนึ่งในนั้นคือการค้นหาองค์ประกอบตามดัชนี เนื่องจากเราชี้ไปที่ดัชนี นั่นคือ ที่อยู่เฉพาะในหน่วยความจำ การค้นหาอาร์เรย์จึงรวดเร็วมาก ArrayList ใน Java ก็สามารถทำได้เช่นกัน! เมื่อต้องการทำเช่นนี้ จะใช้วิธีget():
public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();
   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Hippopotamus");
   Cat philipp = new Cat("Philip Markovich");
   Cat pushok = new Cat("Fluff");

   cats.add(thomas);
   cats.add(behemoth);
   cats.add(philipp);
   cats.add(pushok);

   Cat secondCat = cats.get(1);

   System.out.println(secondCat);
}
บทสรุป:

Cat{name='Бегемот'}
นอกจากนี้คุณยังสามารถค้นหาได้อย่างง่ายดายว่า ArrayList มีวัตถุใดวัตถุหนึ่งหรือไม่ ทำได้โดยใช้วิธีการcontains():
public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();
   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Hippopotamus");
   Cat philipp = new Cat("Philip Markovich");
   Cat pushok = new Cat("Fluff");

   cats.add(thomas);
   cats.add(behemoth);
   cats.add(philipp);
   cats.add(pushok);

   cats.remove(pushok);
   System.out.println(cats.contains(pushok));
}
วิธีการตรวจสอบว่าองค์ประกอบมีอยู่ในอาร์เรย์ภายในของ ArrayList หรือ ไม่ และส่งกลับผลลัพธ์ในรูปแบบboolean- trueหรือ falseบทสรุป:

false
และสิ่งสำคัญอีกประการหนึ่งเกี่ยวกับการแทรก ArrayList ช่วยให้คุณสามารถแทรกข้อมูลไม่เพียงแต่ที่ส่วนท้ายของอาร์เรย์ แต่ยังลงในเซลล์ใดๆ ตามดัชนีด้วย มีสองวิธีสำหรับสิ่งนี้:
  • add(int index, Cat element)
  • set(int index, Cat element)
สำหรับทั้งสองกรณี คุณจะต้องส่งดัชนีของเซลล์ที่คุณต้องการแทรก และลิงก์ไปยังออบเจ็กต์นั้น ข้อแตกต่างคือการวางผ่านset()จะเขียนทับค่าเก่าที่จัดเก็บไว้ในเซลล์ และการแทรกผ่านadd()ขั้นแรกจะเลื่อนองค์ประกอบทั้งหมดโดยเริ่มจาก[index]จุดสิ้นสุดของอาร์เรย์ และเพิ่มวัตถุที่คุณต้องการลงในเซลล์ว่างที่เป็นผลลัพธ์ นี่คือตัวอย่าง:
public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();
   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Hippopotamus");
   Cat philipp = new Cat("Philip Markovich");
   Cat pushok = new Cat("Fluff");

   cats.add(thomas);
   cats.add(behemoth);

   System.out.println(cats.toString());

   cats.set(0, philipp);//Now we have a list of 2 cats. We add the 3rd via set:

   System.out.println(cats.toString());
}
บทสรุป:

[[Cat{name='Томас'}, Cat{name='Бегемот'}]
[Cat{name='Фorпп Маркович'}, Cat{name='Бегемот'}]
เรา มี รายชื่อแมว 2 ตัว เราแทรกอีกตัวหนึ่งผ่านวิธีการset()เข้าไปในเซลล์ 0เป็นผลให้ค่าเก่าที่จัดเก็บไว้ในเซลล์นี้ถูกแทนที่ด้วยค่าใหม่
public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();
   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Hippopotamus");
   Cat philipp = new Cat("Philip Markovich");
   Cat pushok = new Cat("Fluff");

   cats.add(thomas);
   cats.add(behemoth);

   System.out.println(cats.toString());

   cats.add(0, philipp);//Now we have a list of 2 cats. Add the 3rd via add

   System.out.println(cats.toString());
}
แต่มันadd()ทำงานแตกต่างออกไป เขาเลื่อนองค์ประกอบทั้งหมดไปทางขวาแล้วเขียนค่าใหม่ลงใน0เซลล์ บทสรุป:

[Cat{name='Томас'}, Cat{name='Бегемот'}]
[Cat{name='Фorпп Маркович'}, Cat{name='Томас'}, Cat{name='Бегемот'}]
หากต้องการล้างรายการทั้งหมด ให้ใช้วิธีclear():
public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();
   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Hippopotamus");
   Cat philipp = new Cat("Philip Markovich");
   Cat pushok = new Cat("Fluff");

   cats.add(thomas);
   cats.add(behemoth);
   cats.add(philipp);
   cats.add(pushok);

   cats.clear();

   System.out.println(cats.toString());
}
บทสรุป:

[]
เนื้อหาทั้งหมดถูกลบออกจากรายการแล้ว อย่างไรก็ตาม โปรดทราบ: ไม่เหมือนอาร์เรย์ใน ArrayList เมธอด toString() จะถูกแทนที่และแสดงรายการในรูปแบบสตริงทันที ในกรณีของอาร์เรย์ เราต้องใช้คลาส Arrays สำหรับสิ่งนี้ และเนื่องจากเราจำ Arrays ได้: ใน Java คุณสามารถ "สลับ" ระหว่างอาร์เรย์และ ArrayList ได้อย่างง่ายดาย นั่นคือแปลงอาร์เรย์หนึ่งเป็นอีกอาร์เรย์หนึ่ง คลาส Arrays มีเมธอดสำหรับสิ่งนี้ Arrays.asList() ด้วยความช่วยเหลือนี้ เราจึงได้รับเนื้อหาของอาร์เรย์เป็นรายการและส่งผ่านไปยังตัวสร้าง ArrayList ของเรา:
public static void main(String[] args) {

   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Hippopotamus");
   Cat philipp = new Cat("Philip Markovich");
   Cat pushok = new Cat("Fluff");

   Cat[] catsArray = {thomas, behemoth, philipp, pushok};

   ArrayList<Cat> catsList = new ArrayList<>(Arrays.asList(catsArray));
   System.out.println(catsList);
}
บทสรุป:

[Cat{name='Томас'}, Cat{name='Бегемот'}, Cat{name='Фorпп Маркович'}, Cat{name='Пушок'}]
คุณสามารถทำสิ่งที่ตรงกันข้ามได้ - รับอาร์เรย์จากวัตถุ ArrayList เมื่อต้องการทำเช่นนี้ ให้ใช้เมธอด toArray():
public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();

   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Hippopotamus");
   Cat philipp = new Cat("Philip Markovich");
   Cat pushok = new Cat("Fluff");

   cats.add(thomas);
   cats.add(behemoth);
   cats.add(philipp);
   cats.add(pushok);

   Cat[] catsArray = cats.toArray(new Cat[0]);

   System.out.println(Arrays.toString(catsArray));
}
โปรดทราบ: เราได้ส่งผ่านอาร์เรย์ว่างไปยังเมธอด toArray() มันไม่ใช่ความผิดพลาด ภายในคลาส ArrayList วิธีการนี้จะถูกนำมาใช้ในลักษณะที่ส่งผ่านอาร์เรย์ว่างเพื่อเพิ่มประสิทธิภาพ สำหรับตอนนี้ จำสิ่งนี้ไว้ใช้ในอนาคต (แต่คุณสามารถโอนขนาดที่ต้องการได้เช่นกัน ซึ่งจะได้ผล) พูดถึงขนาด. ขนาดปัจจุบันของรายการสามารถพบได้โดยใช้วิธีการsize():
public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();


   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Hippopotamus");
   Cat philipp = new Cat("Philip Markovich");
   Cat pushok = new Cat("Fluff");

   cats.add(thomas);
   cats.add(behemoth);
   cats.add(philipp);
   cats.add(pushok);

   System.out.println(cats.size());
}
สิ่งสำคัญคือต้องเข้าใจในที่นี้ว่าlengthเมธอด ArrayList.size() จะส่งคืนจำนวนองค์ประกอบทุกประการ ไม่ใช่ความจุเริ่มต้น เนื่องจากเราไม่ได้ระบุเมื่อสร้าง ArrayList โดยทั่วไปแล้วสามารถระบุได้ ArrayList มีตัวสร้างที่สอดคล้องกัน แต่พฤติกรรมในแง่ของการเพิ่มองค์ประกอบใหม่จะไม่เปลี่ยนแปลง:
public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>(2);//create an ArrayList with an initial capacity of 2


   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Hippopotamus");
   Cat philipp = new Cat("Philip Markovich");
   Cat pushok = new Cat("Fluff");

   cats.add(thomas);
   cats.add(behemoth);
   cats.add(philipp);
   cats.add(pushok);

   System.out.println(cats.size());
}
เอาต์พุตคอนโซล:

4
เราสร้างรายการที่มี 2 องค์ประกอบ แต่เมื่อเราต้องการมันก็ขยายออกได้อย่างง่ายดาย อีกประการหนึ่งคือหากเราสร้างรายการเล็กๆ ขึ้นมาในตอนแรก รายการนั้นจะต้องดำเนินการขยายบ่อยขึ้น และนี่จะใช้ทรัพยากรจำนวนหนึ่ง ในการบรรยายนี้ เราแทบไม่ได้พูดถึงกระบวนการลบองค์ประกอบออกจาก ArrayList แน่นอนว่านี่ไม่ได้เกิดจากการหลงลืม หัวข้อนี้ถูกแยกออกเป็นบรรยายแยกต่างหากซึ่งคุณสามารถอ่านเพิ่มเติมได้ :)
ความคิดเห็น
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION