CodeGym/Blog Java/Ngẫu nhiên/Danh sách mảng Java

Danh sách mảng Java

Xuất bản trong nhóm
CHÀO! Trong các bài học trước, chúng ta đã tìm hiểu sâu về mảng và xem xét các ví dụ phổ biến về cách làm việc với mảng. Trong bài học này, chúng ta sẽ xem xét kỹ hơn về Java ArrayList. Nói chung, mảng là siêu tiện dụng. Và, như bạn đã nhận thấy, bạn có thể làm được rất nhiều điều với chúng :) Nhưng mảng có một số thiếu sót.
  • Kích thước hạn chế. Bạn cần biết mảng của bạn cần chứa bao nhiêu phần tử tại thời điểm bạn tạo nó. Nếu bạn đánh giá thấp, thì bạn sẽ không có đủ không gian. Đánh giá quá cao và mảng sẽ vẫn trống một nửa, điều này cũng không tốt. Xét cho cùng, bạn vẫn đang phân bổ nhiều bộ nhớ hơn mức cần thiết.

  • Mảng không có phương thức thêm phần tử. Bạn phải luôn chỉ ra rõ ràng chỉ mục của vị trí mà bạn muốn thêm một phần tử. Nếu bạn vô tình chỉ định chỉ mục cho một vị trí bị chiếm giữ bởi một số giá trị mà bạn cần, nó sẽ bị ghi đè.

  • Không có phương pháp nào để xóa một mục. Một giá trị chỉ có thể là "không".
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("Behemoth");
       cats[2] = new Cat("Lionel Messi");

       cats[1] = null;



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

   @Override
   public String toString() {
       return "Cat{" +
               "name='" + name + '\'' +
               '}';
   }
}
Kết quả: [Cat{name='Thomas'}, null, Cat{name='Lionel Messi'}] May mắn thay, những người tạo ra Java đã nhận thức rõ về ưu điểm và nhược điểm của mảng, do đó đã tạo ra một cấu trúc dữ liệu rất thú vị có tên là Java ArrayList . Nói một cách đơn giản nhất có thể, một ArrayList trong Java là một mảng "được cải tiến" với rất nhiều tính năng mới.

Cách tạo một ArrayList

Nó rất dễ dàng để tạo ra:
ArrayList<Cat> cats = new ArrayList<Cat>();
Bây giờ chúng ta đã tạo một danh sách để lưu trữ các đối tượng Cat . Lưu ý rằng chúng tôi không chỉ định kích thước của ArrayList vì nó có thể tự động mở rộng. Sao có thể như thế được? Nó khá đơn giản, thực sự. Nó có thể làm bạn ngạc nhiên, nhưng ArrayList trong Java được xây dựng trên một mảng rất bình thường :) Vâng, nó chứa một mảng, và đó là nơi lưu trữ các phần tử của chúng ta. Nhưng ArrayList trong Java có một cách đặc biệt để làm việc với mảng đó:
  • Khi mảng bên trong được lấp đầy, ArrayList sẽ tạo một mảng mới bên trong. Kích thước của mảng mới bằng kích thước của mảng cũ nhân 1,5 cộng 1.

  • Tất cả dữ liệu được sao chép từ mảng cũ sang mảng mới

  • Mảng cũ được dọn sạch bởi bộ thu gom rác.
Cơ chế này cho phép Java ArrayList (không giống như một mảng thông thường) triển khai một phương thức để thêm các phần tử mới. Đó là add()phương pháp
public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<Cat>();
   cats.add(new Cat("Behemoth"));
}
Các mục mới được thêm vào cuối danh sách. Bây giờ không có nguy cơ tràn mảng, vì vậy phương pháp này hoàn toàn an toàn. Nhân tiện, ArrayList không chỉ có thể tìm một đối tượng theo chỉ mục của nó mà còn ngược lại: nó có thể sử dụng một tham chiếu để tìm chỉ mục của một đối tượng trong ArrayList ! Đây là mục đích của phương thức indexOf() : Chúng ta chuyển một tham chiếu đến đối tượng mà chúng ta muốn và indexOf() trả về chỉ mục của nó:
public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();
   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Behemoth");
   Cat lionel = new Cat("Lionel Messi");
   Cat fluffy = new Cat ("Fluffy");

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

   int thomasIndex = cats.indexOf(thomas);
   System.out.println(thomasIndex);
}
Đầu ra: 0 Đúng vậy. Đối tượng thomas của chúng tôi thực sự được lưu trữ trong phần tử 0. Mảng không chỉ có nhược điểm. Họ cũng có những lợi thế không thể nghi ngờ. Một trong số đó là khả năng tìm kiếm các phần tử theo chỉ mục. Vì chúng ta trỏ đến một chỉ mục, tức là đến một địa chỉ bộ nhớ cụ thể, nên việc tìm kiếm một mảng theo cách này rất nhanh chóng. ArrayListcũng biết làm! Phương thức get () thực hiện điều này:
public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();
   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Behemoth");
   Cat lionel = new Cat("Lionel Messi");
   Cat fluffy = new Cat ("Fluffy");

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

   Cat secondCat = cats.get(1);

   System.out.println(secondCat);
}
Đầu ra: Cat{name='Behemoth'} Ngoài ra, bạn có thể dễ dàng tìm hiểu xem ArrayList có chứa một đối tượng cụ thể hay không. Điều này được thực hiện bằng cách sử dụng phương thức ArrayList contains():
public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();
   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Behemoth");
   Cat lionel = new Cat("Lionel Messi");
   Cat fluffy = new Cat ("Fluffy");

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

   cats.remove(fluffy);
   System.out.println(cats.contains(fluffy));
}
Phương thức này kiểm tra xem mảng bên trong của ArrayList có chứa phần tử hay không và trả về một giá trị boolean (đúng hoặc sai). Đầu ra: sai Và một điều quan trọng khác về chèn. ArrayList cho phép bạn sử dụng một chỉ mục để chèn các phần tử không chỉ vào cuối mảng mà còn ở bất kỳ đâu. Nó có hai phương pháp cho việc này:
  • Thêm ArrayList (chỉ số int, phần tử Cat)
  • Bộ ArrayList (chỉ số int, phần tử Cat)
Là đối số, cả hai phương thức này đều lấy chỉ mục của vị trí mà bạn muốn chèn và tham chiếu đến chính đối tượng đó. Sự khác biệt là việc chèn sử dụng set() sẽ ghi đè lên giá trị cũ. Việc chèn bằng cách sử dụng add() trước tiên sẽ dịch chuyển tất cả các phần tử từ [chỉ mục] đến cuối mảng, sau đó thêm đối tượng đã chỉ định vào vị trí trống kết quả.

Đây là một ví dụ:

public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();
   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Behemoth");
   Cat lionel = new Cat("Lionel Messi");
   Cat fluffy = new Cat ("Fluffy");

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

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

   cats.set(0, lionel);// Now we have a list of 2 cats. Adding a 3rd using set

   System.out.println(cats.toString());
}
Kết quả: [[Cat{name='Thomas'}, Cat{name='Behemoth'}] [Cat{name='Lionel Messi'}, Cat{name='Behemoth'}] Chúng ta có một danh sách gồm 2 con mèo . Sau đó, chúng tôi đã chèn một phần tử khác làm phần tử 0 bằng phương thức set() . Kết quả là phần tử cũ đã được thay thế bằng phần tử mới.
public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();
   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Behemoth");
   Cat lionel = new Cat("Lionel Messi");
   Cat fluffy = new Cat ("Fluffy");

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

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

   cats.add(0, lionel);// Now we have a list of 2 cats. Adding a 3rd using add

   System.out.println(cats.toString());
}
Và ở đây chúng ta thấy rằng add() hoạt động khác đi. Nó di chuyển tất cả các phần tử sang bên phải và sau đó ghi giá trị mới là phần tử 0. Kết quả: [Cat{name='Thomas'}, Cat{name='Behemoth'}] [Cat{name='Lionel Messi'}, Cat{name='Thomas'}, Cat{name='Behemoth'}] Để xóa hoàn toàn danh sách, chúng ta sử dụng phương thức clear() :
public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();
   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Behemoth");
   Cat lionel = new Cat("Lionel Messi");
   Cat fluffy = new Cat ("Fluffy");

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

   cats.clear();

   System.out.println(cats.toString());
}
Kết quả: [] Mọi thứ đã bị xóa khỏi danh sách. Nhân tiện, xin lưu ý: không giống như mảng, ArrayList ghi đè phương thức toString() và đã hiển thị danh sách một cách thích hợp dưới dạng chuỗi. Với các mảng thông thường, chúng ta phải sử dụng lớp Arrays cho việc này. Và vì tôi đã đề cập đến Mảng : Java cho phép bạn dễ dàng "chuyển đổi" giữa một mảng và một ArrayList , tức là chuyển đổi cái này sang cái khác. Lớp Arrays có phương thức Arrays.asList() cho việc này. Chúng tôi sử dụng nó để lấy nội dung dưới dạng một mảng và chuyển chúng tới hàm tạo ArrayList của chúng tôi :
public static void main(String[] args) {

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


   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Behemoth");
   Cat lionel = new Cat("Lionel Messi");
   Cat fluffy = new Cat ("Fluffy");

   Cat[] catsArray = {thomas, behemoth, lionel, fluffy};

   ArrayList<Cat> catsList = new ArrayList<>(Arrays.asList(catsArray));
   System.out.println(catsList);
}
Đầu ra: [Cat{name='Thomas'}, Cat{name='Behemoth'}, Cat{name='Lionel Messi'}, Cat{name='Fluffy'}] Bạn cũng có thể đi theo hướng ngược lại: nhận một mảng từ một đối tượng ArrayList . Chúng tôi làm điều này bằng phương thức toArray() :
public static void main(String[] args) {

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

   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Behemoth");
   Cat lionel = new Cat("Lionel Messi");
   Cat fluffy = new Cat ("Fluffy");

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

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

   System.out.println(Arrays.toString(catsArray));
}
Lưu ý: chúng tôi đã chuyển một mảng trống cho phương thức toArray() . Đây không phải là một lỗi. Bên trong lớp ArrayList , phương thức này được triển khai theo cách mà việc truyền một mảng trống sẽ làm tăng hiệu suất của nó. Chỉ cần ghi nhớ điều này cho tương lai (tất nhiên, bạn có thể chuyển một mảng có kích thước cụ thể; điều đó cũng sẽ hiệu quả). Ồ, về kích thước. Kích thước hiện tại của danh sách có thể được tìm thấy bằng phương thức size() :
public static void main(String[] args) {

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


   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Behemoth");
   Cat lionel = new Cat("Lionel Messi");
   Cat fluffy = new Cat ("Fluffy");

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

   System.out.println(cats.size());
}
Điều quan trọng cần hiểu là không giống như thuộc tính độ dài của mảng , phương thức ArrayList.size() trả về số phần tử thực tế, không phải dung lượng ban đầu. Rốt cuộc, chúng tôi đã không chỉ định kích thước khi tạo ArrayList . Tuy nhiên, bạn có thể chỉ định nó — ArrayList có một hàm tạo phù hợp. Nhưng về việc thêm các yếu tố mới, điều này không thay đổi hành vi của nó:
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("Behemoth");
   Cat lionel = new Cat("Lionel Messi");
   Cat fluffy = new Cat ("Fluffy");

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

   System.out.println(cats.size());
}
Đầu ra bảng điều khiển: 4 Chúng tôi đã tạo một danh sách gồm 2 phần tử, nhưng danh sách này sẽ lặng lẽ mở rộng khi chúng tôi cần. Một cân nhắc khác là nếu ban đầu chúng ta tạo một danh sách rất nhỏ thì danh sách đó sẽ phải mở rộng thường xuyên hơn, điều này sẽ sử dụng một số tài nguyên. Chúng ta hầu như không đề cập đến quá trình loại bỏ các phần tử khỏi một ArrayList trong bài học này. Chúng tôi đã đưa chủ đề này vào một bài học riêng mà bạn sẽ gặp sau :) Để củng cố những gì bạn đã học, chúng tôi khuyên bạn nên xem một bài học video từ Khóa học Java của chúng tôi
Bình luận
  • Phổ biến
  • Mới
Bạn phải đăng nhập để đăng nhận xet
Trang này chưa có bất kỳ bình luận nào