К сожалению, в одну статью вся информация не поместилась, поэтому продолжаем разбираться с оставшимися методами класса ArrayList.
Отсортировать коллекцию:
public void sort(Comparator< ? super E> c)
Осуществляет сортировку списка по заданному правилу. Правило сортировки представляет собой реализованный интерфейс Comparator с переопределенным методом compare()
. Переопределение нужно, если коллекция содержит объекты собственного класса. При работе со стандартными классами (Integer, String и так далее) переопределение compare обычно требуется только для нестандартной сортировки.
Создадим класс 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;
}
}
Напишем простой компаратор, который будет сравнивать id студентов:
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 David, 2 Tom, 5 Rohit, 1 Paul, 3 Vishal] превратится в [1 Paul, 2 Tom, 3 Vishal, 4 David, 5 Rohit].
Напоследок я оставил очень интересный, но редко кем используемый метод:
public List<E> subList(int fromIndex, int toIndex)
Он возвращает не новый список, как может показаться, а вид (view) списка (подсписок), для которого этот метод был вызван, таким образом, что оба списка станут разделять хранимые элементы. 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; //записываем в конец списка новое значение
size++; //увеличиваем значение переменной размера списка
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] вместо [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]; //сохраняем в доп. переменную значение удаляемого элемента
System.arraycopy(temp, 0, elements, 0, index); //копируем левую часть массива до указанного индекса
System.arraycopy(temp, index + 1, elements, index, temp.length - index - 1); //копируем правую часть массива после указанного индекса
size--; //уменьшаем значение переменной
return value;
}
}
Список использованных источников:
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ