#java #arraylist
#java #arraylist
Вопрос:
Я должен реализовать пользовательский класс ArrayList. Мы не можем использовать arrayCopy. Мне нужно иметь возможность удалять строку из массива, а затем перемещать все элементы влево на один индекс. Моя попытка приведена ниже, пожалуйста, помогите.
/****************************************************************************
* Removes the string at the specified index from the list,
* if it is present and shifts the remaining elements left.
*
* @param str value to remove from list
* @return the value removed from the list
* @throws IndexOutOfBoundsException if index is invalid
*/
public String remove(int index){
if (index < 0 || index >= this.myArray.length)
{
throw new IndexOutOfBoundsException("Index out of bounds.");
}
else {
String removed = this.myArray[index];
this.myArray[index] = null;
String [] temp = new String[this.myArray.length-1];
for(int i = 0; i<this.myArray.length; i ){
if (this.myArray[i] != null){
temp[i] = this.myArray[i];
}
}
return removed;
}
}
Я продолжаю получать IndexOutOfBoundsException
at temp[i] = this.myArray[i]
.
Комментарии:
1. В чем ваш вопрос?
2. Я продолжаю получать исключение IndexOutOfBoundsException.
3. В какой строке вы получаете исключение?
4. temp[i] = this. myArray[i];
5. for(int i = index 1; i < myArray.length; i ){ myArray[i-1] = myArray[i] }
Ответ №1:
Вы создаете temp
массив с одним меньшим количеством элементов, чем this.myArray
. Затем вы перебираете все индексы myArray
и используете эти индексы для записи temp[i]
. Последний из них выходит за рамки, поскольку temp
он на единицу меньше.
Отладчик поможет вам найти это. Вы также можете поместить a System.out.println("about to access index " i)
перед любой строкой, которая обращается к массиву, и посмотреть, какая строка печатается прямо перед исключением. Затем вам просто нужно выяснить, к какому индексу вы собираетесь получить доступ (он прямо там, в стандартном выводе), и подумать о том, насколько велик массив, к которому вы собираетесь получить доступ.
Комментарии:
1. Теперь у меня новая проблема. Он не обновляет позиции элементов в массиве. Поэтому, когда я вызываю myArray.remove(1), он оставляет null в индексе один. Затем, когда я снова вызываю метод, размер уменьшается на единицу, но массив не меняется, потому что элементы не сдвигались.
2. @user3791101 Я бы настоятельно рекомендовал вам сделать паузу и продумать все по одному шагу за раз. Что вам нужно сделать, чтобы удалить элемент в индексе
i
? У вас была куча последовательно упорядоченных блоков, и вы хотели удалить элемент из одного, как это делает список массива. Какие отдельные шаги требуются? Как бы вы (не компьютер) это сделали? Может быть, даже вырезать несколько кусочков бумаги и попробовать. Мы могли бы дать вам ответ, но думать о том, как его получить, является важной частью обучения.3. Я бы добавлял элементы один за другим, пока не доберусь до индекса, затем пропустил это и добавил элементы в индекс-1, чтобы компенсировать это недостающее значение.
4. Это определенно разумный способ. Итак, попробуйте. Если у вас есть конкретные вопросы при написании этого, вы можете задать их в качестве нового вопроса. Но вам обязательно нужно сначала попробовать действительно хорошо, в том числе попытаться отладить, если что-то работает не так, как вы ожидаете. Я знаю, что это похоже на удар головой о стену — мы все были там — но такие вещи действительно делают вас лучшим программистом. В какой-то момент вы должны будете иметь возможность отлаживать свои программы. Лучше учиться по ходу дела, чем доходить до написания огромных программ и внезапно нуждаться в том, чтобы научиться отлаживать.
Ответ №2:
temp
Массив на единицу короче, поэтому он не может вместить все.
Вам нужно пропустить нужный индекс при копировании массива.
Приведенный ниже код делает это, используя две разные переменные для индексов в старом и новом массивах.
Он пропускает увеличение одного из них при обнаружении удаленного индекса.
public String remove(int index) {
if (index < 0 || index >= this.myArray.length) {
// FYI, this would be thrown anyway; not sure if you need to do it
throw new IndexOutOfBoundsException("Index out of bounds.");
}
String removed = this.myArray[index];
String[] temp = new String[this.myArray.length - 1];
for(int i = 0, j = 0; i < this.myArray.length; i ){
if (i != index) {
temp[j ] = this.myArray[i];
}
// otherwise, j does not get incremented
}
this.myArray = temp; // don't forget this!
return removed;
}
Комментарии:
1. Ой, я неправильно прочитал и не увидел ваш
j
. Извините, игнорируйте меня. 🙂