Skip to content

Instantly share code, notes, and snippets.

@untainsYD
Created May 15, 2025 07:15
Show Gist options
  • Save untainsYD/c216352a0b8204ce865fec1aa12989c1 to your computer and use it in GitHub Desktop.
Save untainsYD/c216352a0b8204ce865fec1aa12989c1 to your computer and use it in GitHub Desktop.
Створення власного контейнера на базі масиву
package lab4.container;
import java.util.AbstractList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.ListIterator;
import java.util.NoSuchElementException;
import java.util.Objects;
/**
* Узагальнений клас, що представляє одновимірний масив з діапазоном індексів від from до to (включно)
* @param <E> тип елементів масиву
*/
public class IndexedArray<E> extends AbstractList<E> {
private final Object[] elements;
private final int from;
private final int to;
/**
* Конструктор за замовчуванням, створює порожній масив з індексами від 0 до -1
*/
public IndexedArray() {
this(0, -1);
}
/**
* Створює порожній масив із заданим діапазоном індексів
* @param from початковий індекс (включно)
* @param to кінцевий індекс (включно)
*/
public IndexedArray(int from, int to) {
if (to < from) {
throw new IllegalArgumentException("Кінцевий індекс не може бути меншим за початковий: from=" + from + ", to=" + to);
}
this.from = from;
this.to = to;
int size = to - from + 1;
this.elements = new Object[size];
}
/**
* Створює масив із заданим діапазоном індексів та колекцією елементів
* @param from початковий індекс (включно)
* @param to кінцевий індекс (включно)
* @param collection колекція елементів
*/
public IndexedArray(int from, int to, Collection<? extends E> collection) {
if (to < from) {
throw new IllegalArgumentException("Кінцевий індекс не може бути меншим за початковий: from=" + from + ", to=" + to);
}
int size = to - from + 1;
if (collection.size() > size) {
throw new IllegalArgumentException("Розмір колекції перевищує розмір масиву");
}
this.from = from;
this.to = to;
this.elements = new Object[size];
int i = 0;
for (E element : collection) {
elements[i++] = element;
}
}
/**
* Створює масив із заданим діапазоном індексів та масивом елементів
* @param from початковий індекс (включно)
* @param to кінцевий індекс (включно)
* @param elements масив елементів
*/
@SafeVarargs
public IndexedArray(int from, int to, E... elements) {
if (to < from) {
throw new IllegalArgumentException("Кінцевий індекс не може бути меншим за початковий: from=" + from + ", to=" + to);
}
int size = to - from + 1;
if (elements.length > size) {
throw new IllegalArgumentException("Розмір масиву елементів перевищує розмір створюваного масиву");
}
this.from = from;
this.to = to;
this.elements = new Object[size];
System.arraycopy(elements, 0, this.elements, 0, elements.length);
}
/**
* Перевіряє чи належить індекс допустимому діапазону
* @param index індекс для перевірки
* @return true, якщо індекс допустимий
*/
private boolean isValidIndex(int index) {
return index >= from && index <= to;
}
/**
* Перетворює зовнішній індекс на внутрішній (зсунутий відносно from)
* @param externalIndex зовнішній індекс
* @return внутрішній індекс
*/
private int toInternalIndex(int externalIndex) {
if (!isValidIndex(externalIndex)) {
throw new IndexOutOfBoundsException("Індекс поза межами допустимого діапазону: " + externalIndex +
", допустимий діапазон: [" + from + ".." + to + "]");
}
return externalIndex - from;
}
/**
* Перетворює внутрішній індекс на зовнішній
* @param internalIndex внутрішній індекс
* @return зовнішній індекс
*/
private int toExternalIndex(int internalIndex) {
return internalIndex + from;
}
/**
* Повертає розмір масиву
* @return кількість елементів
*/
@Override
public int size() {
return to - from + 1;
}
/**
* Перевіряє чи порожній масив
* @return true, якщо масив порожній
*/
@Override
public boolean isEmpty() {
return size() == 0;
}
/**
* Перевіряє чи містить масив заданий елемент
* @param o елемент для перевірки
* @return true, якщо елемент знайдено
*/
@Override
public boolean contains(Object o) {
return indexOf(o) >= from;
}
/**
* Повертає ітератор для обходу елементів масиву
* @return ітератор
*/
@Override
public Iterator<E> iterator() {
return new Iterator<E>() {
private int cursor = 0;
@Override
public boolean hasNext() {
return cursor < size();
}
@SuppressWarnings("unchecked")
@Override
public E next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
return (E) elements[cursor++];
}
};
}
/**
* Повертає масив, що містить всі елементи
* @return масив об'єктів
*/
@Override
public Object[] toArray() {
return Arrays.copyOf(elements, size());
}
/**
* Повертає масив заданого типу, що містить всі елементи
* @param a масив, в який будуть скопійовані елементи
* @return масив елементів
*/
@Override
@SuppressWarnings("unchecked")
public <T> T[] toArray(T[] a) {
int size = size();
if (a.length < size) {
return (T[]) Arrays.copyOf(elements, size, a.getClass());
}
System.arraycopy(elements, 0, a, 0, size);
if (a.length > size) {
a[size] = null;
}
return a;
}
/**
* Цей метод не підтримується, оскільки масив має фіксований розмір
*/
@Override
public boolean add(E e) {
throw new UnsupportedOperationException("Масив має фіксований розмір");
}
/**
* Цей метод не підтримується, оскільки масив має фіксований розмір
*/
@Override
public boolean remove(Object o) {
throw new UnsupportedOperationException("Масив має фіксований розмір");
}
/**
* Перевіряє чи містить масив усі елементи із заданої колекції
* @param c колекція для перевірки
* @return true, якщо всі елементи знайдено
*/
@Override
public boolean containsAll(Collection<?> c) {
for (Object e : c) {
if (!contains(e)) {
return false;
}
}
return true;
}
/**
* Цей метод не підтримується, оскільки масив має фіксований розмір
*/
@Override
public boolean addAll(Collection<? extends E> c) {
throw new UnsupportedOperationException("Масив має фіксований розмір");
}
/**
* Цей метод не підтримується, оскільки масив має фіксований розмір
*/
@Override
public boolean addAll(int index, Collection<? extends E> c) {
throw new UnsupportedOperationException("Масив має фіксований розмір");
}
/**
* Цей метод не підтримується, оскільки масив має фіксований розмір
*/
@Override
public boolean removeAll(Collection<?> c) {
throw new UnsupportedOperationException("Масив має фіксований розмір");
}
/**
* Цей метод не підтримується, оскільки масив має фіксований розмір
*/
@Override
public boolean retainAll(Collection<?> c) {
throw new UnsupportedOperationException("Масив має фіксований розмір");
}
/**
* Встановлює всі елементи масиву в null
*/
@Override
public void clear() {
Arrays.fill(elements, null);
}
/**
* Повертає елемент за заданим індексом
* @param index індекс елемента
* @return елемент
*/
@Override
@SuppressWarnings("unchecked")
public E get(int index) {
return (E) elements[toInternalIndex(index)];
}
/**
* Встановлює нове значення елемента за заданим індексом
* @param index індекс елемента
* @param element нове значення
* @return попереднє значення
*/
@Override
@SuppressWarnings("unchecked")
public E set(int index, E element) {
int internalIndex = toInternalIndex(index);
E oldValue = (E) elements[internalIndex];
elements[internalIndex] = element;
return oldValue;
}
/**
* Цей метод не підтримується, оскільки масив має фіксований розмір
*/
@Override
public void add(int index, E element) {
throw new UnsupportedOperationException("Масив має фіксований розмір");
}
/**
* Цей метод не підтримується, оскільки масив має фіксований розмір
*/
@Override
public E remove(int index) {
throw new UnsupportedOperationException("Масив має фіксований розмір");
}
/**
* Знаходить індекс першого входження заданого елемента
* @param o елемент для пошуку
* @return індекс елемента або -1, якщо елемент не знайдено
*/
@Override
public int indexOf(Object o) {
for (int i = 0; i < elements.length; i++) {
if (Objects.equals(o, elements[i])) {
return toExternalIndex(i);
}
}
return -1;
}
/**
* Знаходить індекс останнього входження заданого елемента
* @param o елемент для пошуку
* @return індекс елемента або -1, якщо елемент не знайдено
*/
@Override
public int lastIndexOf(Object o) {
for (int i = elements.length - 1; i >= 0; i--) {
if (Objects.equals(o, elements[i])) {
return toExternalIndex(i);
}
}
return -1;
}
/**
* Повертає рядкове представлення масиву
* @return рядок з елементами масиву
*/
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("IndexedArray{");
sb.append("range=[").append(from).append("..").append(to).append("], ");
sb.append("elements=[");
for (int i = from; i <= to; i++) {
if (i > from) {
sb.append(", ");
}
sb.append(i).append(":").append(get(i));
}
sb.append("]}");
return sb.toString();
}
/**
* Повертає початковий індекс масиву
* @return початковий індекс
*/
public int getFrom() {
return from;
}
/**
* Повертає кінцевий індекс масиву
* @return кінцевий індекс
*/
public int getTo() {
return to;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment