Вопрос

Я создал связанный список с функциями вставки, поиска и удаления.Я также создал для него итератор.Теперь предположим, что я делаю это:

myList<Integer> test = new myList();
test.insert(30);
test.insert(20);
test.insert(10);
myList.iterator it = test.search(20);
if(it.hasNext())
    System.out.println(it.next());

И вуаля, это работает (печатает значение элемента в узле, в данном случае 20).Теперь, если я сделаю это:

myList<Double> test = new myList();
test.insert(30.1);
test.insert(20.1);
test.insert(10.1);
myList.iterator it = test.search(20.1);
if(it.hasNext())
    System.out.println(it.next());

Это не так, потому что итератор указывает на ноль.Вот реализация функции поиска:

public iterator search(T data)
{
    no<T> temp = first;
    while( (temp != null) && (temp.data != data) )
        temp = temp.next;
    return (new iterator(temp));
}

Вот откуда я знаю, что в сравнениях есть что-то подозрительное:Если я изменю часть приведенного выше кода следующим образом:

while( (temp != null) && (temp.data != data) )
     System.out.println(temp.data + " " + data);
     temp = temp.next;

Я вижу, как он печатает числа в списке.В какой-то момент он печатает «20,1 20,1» (например).Так как я могу это исправить?Функция кажется правильной, но кажется, что Java неправильно сравнивает числа.

РЕДАКТИРОВАТЬ:кстати, BigDecimal тоже доставил мне такую ​​​​же проблему.

РЕДАКТИРОВАТЬ 2:Equals() сработало, не осознавая, что что-то еще не так.Извини.

Это было полезно?

Решение

Вам не нужен для этого оператор !=.Он сравнивает ссылки.Вы хотите .equals() метод:

public iterator search(T data)
{
    no<T> temp = first;
    while (!data.equals(temp.data)) {
        temp = temp.next;
    }
    return (new iterator(temp));
}

Также следите за автобокс.Вы можете найти это test.search(20.1) коробки 20,1 к а Float не Double, что, вероятно, нарушит ваше сравнение.Сравните результаты с test.search(20.1d).Если я правильно помню, выражение:

new Float(20.1).equals(new Double(20.1))

является ложным.

Другие советы

Обратите внимание, что использование .equals() сравнивать парный разряд может привести к ошибкам. Double.equals() использует это как проверку равенства:

 d1.doubleValue() == d2.doubleValue()

Парный разряд и плавает являются приближения чисел, хранящихся в фиксированном месте памяти.

Чтобы правильно сравнить числа с плавающей запятой, вы должны знать, что из-за природы плавающих чисел возникнут некоторые ошибки.

видеть: http://www.google.com/search?q=floating+point+equality

Быстрый и простой способ сравнить двойные числа — использовать Math.abs(a-b)<ACCEPTABLE_ERRORгде может быть ACCEPTABLE_ERROR .000000000001 в зависимости от того, что именно вы делаете.(Обратите внимание, что это не обрабатывает крайние случаи, такие как NaN и INFINITY)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top