У меня есть метод get для моего односвязного списка, и они работают нормально, но мой инструктор сказал мне, что он хочет, чтобы я сократил код, потому что у меня слишком много особых случаев. Проблема в том, что, когда я пытаюсь вырезать некоторые части своего кода, код больше не работает так, как должен.

Код, написанный мной:

public E get(int index) {
    Node<E> f = first;

    // If index is bigger / smaller than Linked List size throw IndexOutOfBounds
    if (index > size || index < 0){
        throw new IndexOutOfBoundsException();
    }


    // Index Less than size and is not the first or last node.
    if (index < size && index > 0) {
        for (int i = 0; i < index; i++) {
            f = f.next;
        }
        return f.getValue();
    }

    // If the Linked List is empty + Index = 0 return null
    if (first == null && index == 0) {
        return null;
    }

    // If Linked List is not empty and index = 0 return first value
    if (index == 0) {
        return first.getValue();
    }

    // If index = end of list
    if (index == size) {
        return last.getValue();
    }


    // Return null if not found.
    return null;

}

Итак, он говорит мне, что я слишком много об этом думаю и нужны только два случая, действительный индекс или недействительный; в чем я согласен с ним, поэтому я пытаюсь сократить свой код до следующего:

Node<E> f = first;

// If index is bigger / smaller than Linked List size throw IndexOutOfBounds
if (index > size || index < 0){
    throw new IndexOutOfBoundsException();
}


// Index Less than size and is not the first or last node.
if (index <= size && index >= 0) {
    for (int i = 0; i < index; i++) {
        f = f.next;
    }
}
return f.getValue();

И для моих тестовых случаев я использую связанный список со следующими значениями:

[Фрэнк, Джордж, Джош, Джим, Женитьба, Сьюзи, Джон, Джим, Дакота, Леви, Джексон, Джефф, Уолт, Мэтт]

И мои тестовые примеры в моем тестовом классе следующие:

System.out.println("Get Method Test ----------------------------");
System.out.println("First Index: " + ll.get(0));
System.out.println("Last Index: " + ll.get(ll.size()));
System.out.println("'Middle' Index: " + ll.get(5));
System.out.println("Empty list with index of 0: " + llempty.get(0));

Что бросает NullPointerException во втором тестовом примере попытки получить последний индекс:

Выход:

First Index: Frank
Exception in thread "main" java.lang.NullPointerException

Мне нужно продемонстрировать следующее:

Тестовые случаи: нулевой индекс, индекс в конце списка, индекс в «середине» списка, пустой список с индексом 0, слишком большой индекс, слишком маленький индекс.

Так что я застрял здесь, ребята / девушки, любая помощь будет оценена!

-1
Frank R 23 Апр 2016 в 15:40

4 ответа

Лучший ответ

В вашем коде есть два случая одной и той же ошибки. Вы должны понимать, что индекс является относительным нулем, что означает, что последний элемент в списке размера n будет иметь индекс n-1. Первая ошибка в вашем новом методе get():

// If index is bigger / smaller than Linked List size throw IndexOutOfBounds
if (index > size || index < 0){
    throw new IndexOutOfBoundsException();
}

Здесь вы должны проверить index >= size следующим образом:

// If index is bigger / smaller than Linked List size throw IndexOutOfBounds
if (index >= size || index < 0){
    throw new IndexOutOfBoundsException();
}

Вторая ошибка в вашем тестовом коде. Где ты пишешь

System.out.println("Last Index: " + ll.get(ll.size()));

Вы должны использовать ll.size() - 1 следующим образом:

System.out.println("Last Index: " + ll.get(ll.size() - 1));

Обе эти вещи наблюдались другими. Однако необходимо исправить и то, и другое.

Когда я внес эти изменения и запустил ваш тест, он добрался до последней строки и выбросил IndexOutOfBoundsException, как и ожидалось. Я также протестировал «Слишком маленький индекс» и «Слишком большой индекс» и получил IndexOutOfBoundsException.

1
Erick G. Hagstrom 23 Апр 2016 в 14:04

Должны были быть

if (index >= size || index < 0){
        throw new IndexOutOfBoundsException();
    }

if (index < size && index >= 0) {
    for (int i = 0; i < index; i++) {
        f = f.next;
    }
}
0
Arun George 23 Апр 2016 в 13:02

Возможно, это не единственная причина (вы показали нам только части кода), но вы испортили значение 'size', потому что, если индекс начинается с 0 (как обычно), последний элемент должен быть в

index == size -1
0
J Fabian Meier 23 Апр 2016 в 12:45

Я бы просто сделал ваш код еще более простым (второй if вокруг вашего цикла не нужен):

//assume 0 based index
int current = 0;

//loop until we hit the requested index
while (current != index) {
 f = f.next;
 current++;
}

//return the right node
return f;

Предполагая, что ваша первоначальная проверка индекса за пределами допустимого диапазона верна, это никогда не должно вызывать у вас проблем. Однако, если ваши индексы основаны на 0, вам необходимо изменить проверку выхода за границы на:

if (index > size - 1 || index < 0) {

Например, если есть 2 элемента, у вас есть индексы 0 и 1. Индекс 2 в этом случае недействителен.

1
nhouser9 23 Апр 2016 в 12:46