JavaRush /בלוג Java /Random-HE /ניתוח מפורט של המחלקה ArrayList [חלק 2]
Vonorim
רָמָה

ניתוח מפורט של המחלקה ArrayList [חלק 2]

פורסם בקבוצה
למרבה הצער, כל המידע לא התאים למאמר אחד, אז אנחנו ממשיכים לבחון את השיטות הנותרות של המחלקה ArrayList. מיין אוסף:
public void sort(Comparator< ? super E> c)
ממיין את הרשימה לפי כלל נתון. כלל מיון הוא ממשק Comparator מיושם עם compare(). דריסה נחוצה אם האוסף מכיל אובייקטים מהמחלקה שלו. כאשר עובדים עם מחלקות סטנדרטיות (Integer, String וכן הלאה), יש צורך בדרך כלל בעקיפה של השוואה רק למיון לא סטנדרטי. בואו ניצור כיתה 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;
 }
}
בואו נכתוב משווה פשוט שישווה את זיהויי התלמידים:
class StudentIdComparator implements Comparator<student>{

 public int compare(Student e1, Student e2) {
  return e1.id.compareTo(e2.id);
 }
}
בואו ניצור רשימה לתלמידים ואובייקט כיתתי שמיישם Comparator:
ArrayList<Student> myList = new ArrayList<> ();
StudentIdComparator comparator = new StudentIdComparator();
בואו נקרא לשיטה sortלרשימה שלנו ונעביר אליה את המשווה:
myList.sort(comparator);
זה יהפוך את הרשימה המקורית [4 דוד, 2 טום, 5 רוהיט, 1 פול, 3 וישאל] ל-[1 פול, 2 טום, 3 וישאל, 4 דוד, 5 רוהיט]. לבסוף השארתי שיטה מאוד מעניינת, אך בשימוש נדיר:
public List<E> subList(int fromIndex, int toIndex)
היא לא מחזירה רשימה חדשה, כפי שזה עשוי להיראות, אלא תצוגה של הרשימה (תת-רשימה) שלשמה נקראה השיטה הזו, כך ששתי הרשימות ישתפו את האלמנטים המאוחסנים. subList היא רשימה פונקציונלית מלאה; היא פועלת גם לכתיבה, תוך ביצוע שינויים מתאימים ברשימת האב. מאפיינים מצוינים נובעים מכך:
someList.subList(3, 7).clear();
בדוגמה זו, someListארבעה אלמנטים יוסרו מהרשימה, מהשלישי עד השביעי (לא כולל). אנו מציינים את טווח העבודה עם הרשימה ויוצאים לדרך. בתוך השיטה, בעצם, יש קריאה למחלקה SubList, שיש לה מימושים משלה של מתודות מוכרות, וכתוצאה מפעולת השיטה מוחזר אובייקט של מחלקה זו. ניתן לראות את היישום של המחלקה עצמה בקוד המקור . כדי לאחד את החומר, אני מציע לך לכתוב יישום משלך של מערך דינמי. זה יהיה מאוד שימושי בעתיד. כדוגמה, אני מציג את היישום שלי של מערך דינמי למספרים בלבד, עם הערות בקוד.
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;
    }
}
רשימת מקורות בשימוש:
  1. קוד מקור ArrayList (נוכחי - JDK 12);
  2. רוב האיורים נלקחו מכאן וכמה מאמרים מ-JavaRush;
  3. מאמר על Habré .
הערות
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION