JavaRush /Blog Java /Random-VI /Phân tích chi tiết lớp ArrayList [Phần 2]
Vonorim
Mức độ

Phân tích chi tiết lớp ArrayList [Phần 2]

Xuất bản trong nhóm
Thật không may, tất cả thông tin không có trong một bài viết, vì vậy chúng ta tiếp tục xem xét các phương thức còn lại của lớp ArrayList. Sắp xếp bộ sưu tập:
public void sort(Comparator< ? super E> c)
Sắp xếp danh sách theo một quy tắc nhất định. Quy tắc sắp xếp là giao diện Bộ so sánh được triển khai với phần ghi đè compare(). Cần ghi đè nếu bộ sưu tập chứa các đối tượng thuộc lớp riêng của nó. Khi làm việc với các lớp tiêu chuẩn (Số nguyên, Chuỗi, v.v.), tính năng ghi đè so sánh thường chỉ cần thiết cho việc sắp xếp không chuẩn. Hãy tạo một lớp Student:
class Student{
 String student_name;
 int id;

 Student(int id, String  student_name){
  this.id = id;
  this.student_name = student_name;
 }

 public String toString(){
  return id + " " + student_name;
 }
}
Hãy viết một bộ so sánh đơn giản để so sánh id sinh viên:
class StudentIdComparator implements Comparator<student>{

 public int compare(Student e1, Student e2) {
  return e1.id.compareTo(e2.id);
 }
}
Hãy tạo một danh sách cho sinh viên và một đối tượng lớp thực hiện Comparator:
ArrayList<Student> myList = new ArrayList<> ();
StudentIdComparator comparator = new StudentIdComparator();
Hãy gọi phương thức sortcho danh sách của chúng ta và chuyển bộ so sánh cho nó:
myList.sort(comparator);
Điều này sẽ biến danh sách ban đầu [4 David, 2 Tom, 5 Rohit, 1 Paul, 3 Vishal] thành [1 Paul, 2 Tom, 3 Vishal, 4 David, 5 Rohit]. Cuối cùng tôi để lại một phương pháp rất thú vị nhưng hiếm khi được sử dụng:
public List<E> subList(int fromIndex, int toIndex)
Có vẻ như nó không trả về một danh sách mới mà là một dạng xem danh sách (danh sách phụ) mà phương thức này được gọi, để cả hai danh sách sẽ chia sẻ các phần tử được lưu trữ. subList là một danh sách đầy đủ chức năng; nó cũng có thể dùng để viết, thực hiện những thay đổi thích hợp cho danh sách cha. Đặc tính tuyệt vời theo sau:
someList.subList(3, 7).clear();
Trong ví dụ này, someListbốn phần tử sẽ bị xóa khỏi danh sách, từ phần tử thứ ba đến phần tử thứ bảy (không bao gồm). Chúng tôi chỉ ra phạm vi để làm việc với danh sách và bắt đầu. Về bản chất, bên trong phương thức này có một lệnh gọi đến lớp SubList, lớp này có cách triển khai riêng các phương thức đã biết và do hoạt động của phương thức đó, một đối tượng của lớp này sẽ được trả về. Việc triển khai chính lớp đó có thể được xem trong nguồn . Để củng cố tài liệu, tôi khuyên bạn nên viết phần triển khai mảng động của riêng mình. Điều này sẽ rất hữu ích trong tương lai. Để làm ví dụ, tôi trình bày cách triển khai mảng động chỉ dành cho số, kèm theo nhận xét trong mã.
public class IntegerArrayList {

    private int [] elements;  //массив, для хранения чисел
    private int size;  //поле-счетчик, которое указывает на количество элементов в массиве
    private static final int DEFAULT_CAPACITY = 10;  //размер массива по умолчанию

    //конструктор без параметров, который создает массив на 10 элементов, если размер не был указан
    public IntegerArrayList(){  //
        this.elements = new int[DEFAULT_CAPACITY];
    }

    //создает массив указанной емкости
    public IntegerArrayList(int initialCapacity){
        if (initialCapacity >= 0){
            this.elements = new int[initialCapacity];
        }
        else {
            throw new IllegalStateException("Capacity can't be less than 0!");
        }
    }

    //получает элемент по указанному индексу
    public int get(int index){
        isIndexExist(index);  //проверка корректности введенного индекса
        return elements[index];
    }

    //возвращает количество элементов в списке
    public int size (){
        return size;
    }

    //добавляем элемент в конец списка
    public boolean add(int value){
        if (size == elements.length){  //если в массиве места нет
            elements = increaseCapacity(); //вызываем метод, который отвечает за увеличение массива
        }
        elements[size] = value; //записываем в конец списка новое meaning
        size++;  //увеличиваем meaning переменной размера списка
        return true;
    }

    //дополнительный закрытый метод для увеличения емкости массива
    private int [] increaseCapacity(){
        int [] temp = new int[(elements.length * 2)];  //создаем новый массив большего размера
        System.arraycopy(elements, 0, temp, 0, elements.length);  //копируем в новый массив элементы из старого массива
        return temp;
    }

    //устанавливает элемент на указанную позицию
    public int set(int value, int index){
        isIndexExist(index);
        int temp = elements[index];
        elements[index] = value;
        return temp;
    }

    //переопределил метод для красивого вывода списка на экран, иначе будут выводиться значения незаполненных ячеек [1, 10] instead of [1, 10, 0, 0...]
    @Override
    public String toString(){
        int [] temp = new int[size];
        System.arraycopy(elements, 0, temp, 0, size);
        return Arrays.toString(temp);
    }

    //проверяем индексы, не выходят ли они за границы массива
    private int isIndexExist(int index){
        if (index >= size || index < 0){
            throw new IndexOutOfBoundsException("Element can't be found! "
                    + "Number of elements in array = " + size
                    + ". Total size of array = " + elements.length);
        }
        return index;
    }

    //проверяем, есть ли элементы в списке
    public boolean isEmpty(){
        return (size == 0);
    }

    //удаляем элемент по индексу
    public int remove (int index){
        isIndexExist(index);  //проверяем индекс
        int [] temp = elements;  //во временный массив заносим ссылку на текущий массив
        elements = new int [temp.length-1];  //полю elements присваиваем ссылку на новый массив размером меньше на 1
        int value = temp[index];  //сохраняем в доп. переменную meaning удаляемого element
        System.arraycopy(temp, 0, elements, 0, index);  //копируем левую часть массива до указанного индекса
        System.arraycopy(temp, index + 1, elements, index, temp.length - index - 1);  //копируем правую часть массива после указанного индекса
        size--;  //уменьшаем meaning переменной
        return value;
    }
}
Danh sách các nguồn được sử dụng:
  1. Mã nguồn ArrayList (hiện tại - JDK 12);
  2. Hầu hết các hình minh họa được lấy từ đây và một số bài viết từ JavaRush;
  3. Bài viết về Habré .
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION