JavaRush /Blog Java /Random-PL /Szczegółowa analiza klasy ArrayList [Część 2]
Vonorim
Poziom 26

Szczegółowa analiza klasy ArrayList [Część 2]

Opublikowano w grupie Random-PL
Niestety nie wszystkie informacje zmieściły się w jednym artykule, dlatego w dalszym ciągu przyglądamy się pozostałym metodom klasy ArrayList. Sortuj kolekcję:
public void sort(Comparator< ? super E> c)
Sortuje listę według podanej reguły. Reguła sortowania to zaimplementowany interfejs komparatora z zastąpionym rozszerzeniem compare(). Przesłonięcie jest konieczne, jeśli kolekcja zawiera obiekty własnej klasy. Podczas pracy ze standardowymi klasami (Integer, String itd.) zastąpienie porównania jest zwykle potrzebne tylko w przypadku sortowania niestandardowego. Stwórzmy klasę 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;
 }
}
Napiszmy prosty komparator, który będzie porównywał legitymacje studenckie:
class StudentIdComparator implements Comparator<student>{

 public int compare(Student e1, Student e2) {
  return e1.id.compareTo(e2.id);
 }
}
Utwórzmy listę dla uczniów i obiekt klasy, który implementuje Comparator:
ArrayList<Student> myList = new ArrayList<> ();
StudentIdComparator comparator = new StudentIdComparator();
Wywołajmy metodę sortdla naszej listy i przekażmy do niej komparator:
myList.sort(comparator);
Spowoduje to przekształcenie oryginalnej listy [4 Dawid, 2 Tom, 5 Rohit, 1 Paweł, 3 Vishal] na [1 Paweł, 2 Tom, 3 Vishal, 4 Dawid, 5 Rohit]. Na koniec zostawiłem bardzo ciekawą, choć rzadko stosowaną metodę:
public List<E> subList(int fromIndex, int toIndex)
Nie zwraca nowej listy, jak mogłoby się wydawać, ale widok listy (podlisty), dla której wywołano tę metodę, tak że obie listy będą współdzielić przechowywane elementy. subList jest listą w pełni funkcjonalną, sprawdza się także przy pisaniu, wprowadzaniu odpowiednich zmian na liście nadrzędnej. Wynikają z tego doskonałe właściwości:
someList.subList(3, 7).clear();
W tym przykładzie someListz listy zostaną usunięte cztery elementy, od trzeciego do siódmego (niewłącznie). Wskazujemy zakres pracy z listą i zaczynamy. Wewnątrz metody zasadniczo następuje wywołanie klasy SubList, która posiada własne implementacje znanych metod, a w wyniku działania metody zwracany jest obiekt tej klasy. Implementację samej klasy można zobaczyć w kodzie źródłowym . Aby utrwalić materiał, sugeruję napisanie własnej implementacji tablicy dynamicznej. Będzie to bardzo przydatne w przyszłości. Jako przykład przedstawiam moją implementację tablicy dynamicznej zawierającej wyłącznie liczby, z komentarzami w kodzie.
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; //записываем в конец списка новое oznaczający
        size++;  //увеличиваем oznaczający переменной размера списка
        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] zamiast [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];  //сохраняем в доп. переменную oznaczający удаляемого element
        System.arraycopy(temp, 0, elements, 0, index);  //копируем левую часть массива до указанного индекса
        System.arraycopy(temp, index + 1, elements, index, temp.length - index - 1);  //копируем правую часть массива после указанного индекса
        size--;  //уменьшаем oznaczający переменной
        return value;
    }
}
Lista wykorzystanych źródeł:
  1. kod źródłowy ArrayList (aktualny - JDK 12);
  2. Większość ilustracji została wzięta stąd i niektóre artykuły z JavaRush;
  3. Artykuł o Habré .
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION