11package input ;
22
3- import java .util .Iterator ;
4- import java .util .Spliterator ;
3+ import java .util .*;
54import java .util .function .Consumer ;
5+ import java .util .stream .Stream ;
66
7- public class CustomCollection <T > implements Iterable <String > {
7+ /**
8+ * CustomCollection - кастомная реализация динамического массива с автоматическим расширением.
9+ * Поддерживает хранение элементов любого типа, итерацию и базовые операции коллекции.
10+ *
11+ * <p>Коллекция использует внутренний массив для хранения элементов и автоматически
12+ * расширяется при заполнении. Коэффициент расширения: {@value #GROWTH_FACTOR}.
13+ *
14+ * <p>Реализует интерфейс {@link Iterable} для поддержки for-each циклов и стримов.
15+ *
16+ * @param <T> тип элементов, хранимых в коллекции
17+ */
18+ public class CustomCollection <T > implements Iterable <T > {
819 private static final float GROWTH_FACTOR = 1.5f ;
920 private static final int DEFAULT_CAPACITY = 10 ;
1021
1122 private Object [] elements ;
1223 private int size ;
1324
14- // Стандартный конструктор
1525 public CustomCollection () {
1626 this .elements = new Object [DEFAULT_CAPACITY ];
1727 }
1828
19- // Конструктор с заданной величиной
2029 public CustomCollection (int initialCapacity ) {
21- if (initialCapacity < 0 ) {
30+ if (initialCapacity <= 0 ) {
2231 throw new IllegalArgumentException ("Capacity cannot be less then 0" );
2332 }
2433 this .elements = new Object [initialCapacity ];
2534 }
2635
2736 // TODO Конструктор из существующей коллекции, копирует все элементы с ёмкостью равной ёмкости коллекции
2837
29- public boolean add (Object element ) {
38+ public boolean add (T element ) {
3039 // Проверяем достаточно ли места для добавления
3140 if (size == elements .length ) {
32- // Если места не осталось применяем формулу увеличения длинны массива
33- int newCapacity = (int ) (elements .length * GROWTH_FACTOR + 1 );
34- // Создаем новый массив с увеличенной длинной
35- Object [] newElements = new Object [newCapacity ];
36- // Копируем в него элементы из старого массива
37- System .arraycopy (elements ,0 , newElements , 0 , elements .length );
38- this .elements = newElements ;
41+ // Если недостаточно, то увеличиваем размер списка
42+ increaseCapacity (size + 1 );
3943 }
4044 // Добавляем новый элемент на последнюю позицию
4145 elements [size ] = element ;
@@ -44,16 +48,42 @@ public boolean add(Object element) {
4448 return true ;
4549 }
4650
51+ public void removeByIndex (int index ) {
52+ if (index < 0 || index >= size ) {
53+ throw new IndexOutOfBoundsException ("Index cannot be less then 0 or more then " + size );
54+ }
55+ // Вычисляем количество элементов, которые нужно сместить влево после удаления
56+ int numToMove = size - index - 1 ;
57+
58+ if (numToMove > 0 ) {
59+ // Используем System.arraycopy для эффективного копирования части массива:
60+ // 1. elements - исходный массив
61+ // 2. index+1 - начальная позиция в исходном массиве (элемент после удаляемого)
62+ // 3. elements - целевой массив (тот же массив, копируем в себя)
63+ // 4. index - начальная позиция в целевом массиве (на место удаляемого элемента)
64+ // 5. numToMove - количество элементов для копирования
65+ System .arraycopy (elements , index + 1 , elements , index , numToMove );
66+ }
67+ // Уменьшаем size на 1 после копирования в конце массива остался "лишний" элемент и удаляем его
68+ elements [--size ] = null ;
69+ }
70+
71+ public void clear () {
72+ for (int i = 0 ; i < size ; i ++) {
73+ elements [i ] = null ;
74+ }
75+ size = 0 ;
76+ }
77+
4778 public T get (int index ) {
48- if (index < 0 || index > size ) {
79+ if (index < 0 || index >= size ) {
4980 throw new IndexOutOfBoundsException ("Index cannot be less then 0 or more then " + size );
5081 }
5182 return (T ) elements [index ];
5283 }
5384
54- // Проверить почему надо вернуть старый элемент
5585 public T set (int index , T element ) {
56- if (index < 0 || index > size ) {
86+ if (index < 0 || index >= size ) {
5787 throw new IndexOutOfBoundsException ("Index cannot be less then 0 or more then " + size );
5888 }
5989
@@ -62,22 +92,100 @@ public T set(int index, T element) {
6292 return old ;
6393 }
6494
65- public int size () { return size ; }
95+ /**
96+ * Возвращает последовательный {@code Stream} с элементами этой коллекции в качестве источника.
97+ *
98+ * <p>Этот метод позволяет использовать функциональные операции над элементами коллекции.
99+ *
100+ * @return последовательный {@code Stream} элементов этой коллекции
101+ */
102+ public Stream <T > stream () {
103+ return (Stream <T >) Arrays .stream (elements , 0 , size );
104+ }
105+
106+ /**
107+ * Добавляет все элементы из указанной коллекции в конец этой коллекции.
108+ *
109+ * <p>Порядок элементов в целевой коллекции соответствует порядку,
110+ * в котором они возвращаются итератором указанной коллекции.
111+ *
112+ * @param collection коллекция, содержащая элементы для добавления
113+ * @return {@code true} если эта коллекция изменилась в результате вызова
114+ */
115+ public boolean addAll (Collection <? extends T > collection ) {
116+ // Проверяем, что переданная коллекция не null и не пустая
117+ if (collection == null || collection .isEmpty ()) {
118+ // Возвращаем false, так как нечего добавлять
119+ return false ;
120+ }
66121
67- public boolean isEmpty () { return size == 0 ; }
122+ int requiredCapacity = size + collection .size ();
123+ if (requiredCapacity > elements .length ) {
124+ increaseCapacity (requiredCapacity );
125+ }
126+ for (T element : collection ) {
127+ // Добавляем элемент в конец массива
128+ // elements[size] = element - добавляет элемент на текущую позицию
129+ // size++ - увеличивает счетчик элементов
130+ elements [size ++] = element ;
131+ }
132+ return true ;
133+ }
134+
135+ public int size () {
136+ return size ;
137+ }
138+
139+ public boolean isEmpty () {
140+ return size == 0 ;
141+ }
68142
69143 @ Override
70144 public Iterator iterator () {
71- return null ;
145+ return new CustomArrayIterator () ;
72146 }
73147
74- @ Override
75- public void forEach (Consumer action ) {
76- Iterable .super .forEach (action );
148+ // Внутренний клас для итератора
149+ class CustomArrayIterator implements Iterator <T > {
150+ private int cursor = 0 ; // текущая позиция
151+ private int lastRet = -1 ; // индекс последнего возвращенного элемента
152+
153+ public CustomArrayIterator () {
154+ }
155+
156+ public boolean hasNext () {
157+ return cursor < size ;
158+ }
159+
160+ public T next () {
161+ if (!hasNext ()) {
162+ throw new NoSuchElementException ("Элемент отсутствует" );
163+ }
164+ lastRet = cursor ;
165+ T element = (T ) elements [cursor ];
166+ cursor ++;
167+
168+ return element ;
169+ }
170+
171+ public void remove () {
172+ if (lastRet == -1 ) {
173+ throw new IllegalStateException ();
174+ }
175+ removeByIndex (lastRet );
176+ cursor = lastRet ;
177+ lastRet = -1 ;
178+ }
77179 }
78180
79- @ Override
80- public Spliterator spliterator () {
81- return Iterable .super .spliterator ();
181+ /**
182+ * Увеличивает емкость внутреннего массива, чтобы обеспечить минимальную указанную емкость.
183+ * @param minCapacity минимальная требуемая емкость
184+ */
185+ private void increaseCapacity (int minCapacity ) {
186+ int newCapacity = (int ) Math .max (elements .length * GROWTH_FACTOR + 1 , minCapacity );
187+ Object [] newElements = new Object [newCapacity ];
188+ System .arraycopy (elements , 0 , newElements , 0 , size );
189+ elements = newElements ;
82190 }
83191}
0 commit comments