Java LinkedList 迭代器:为什么它们只返回对象?

发布于 2024-10-02 16:41:38 字数 897 浏览 4 评论 0原文

在这里,我将发布我的代码:

    int len = InternalList.size();

    ListIterator<E> forward = InternalList.listIterator( 0 );
    ListIterator<E> backward = InternalList.listIterator( len );
    while( forward.hasNext() && backward.hasPrevious() )
    {
        E next = forward.next();
        E prev = backward.previous();

        // When the object references are the same, we expect to be at the
        // center of the list (for odd-numbered lists?); we're done
        if( next == prev )
            return true;

        // Otherwise, if the object values aren't the same, we're not a
        // palindrome
        if( !((E)next).equals( prev ) )
            return false;
    }

这是内部列表:

private LinkedList<E> InternalList;

所以基本上我的问题是最后一个 if 语句仅检查 Object 的 equals() 方法;不是 E 的 equals()。如果强行施法不起作用,那怎么办呢?

Here, I'll just post my code:

    int len = InternalList.size();

    ListIterator<E> forward = InternalList.listIterator( 0 );
    ListIterator<E> backward = InternalList.listIterator( len );
    while( forward.hasNext() && backward.hasPrevious() )
    {
        E next = forward.next();
        E prev = backward.previous();

        // When the object references are the same, we expect to be at the
        // center of the list (for odd-numbered lists?); we're done
        if( next == prev )
            return true;

        // Otherwise, if the object values aren't the same, we're not a
        // palindrome
        if( !((E)next).equals( prev ) )
            return false;
    }

And here's the internal list:

private LinkedList<E> InternalList;

So basically my problem is the last if statement only checks Object's equals() method; not the E's equals(). If forcibly casting it doesn't work, what does?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

っ〆星空下的拥抱 2024-10-09 16:41:38

从迭代器返回的元素的运行时类型不会(而且实际上不能)更改。它们被分配给 E 类型的字段,这些字段很可能在运行时被删除为 Object(取决于通用边界),但这不会影响对象本身。

当调用 equals() 时,它是一个非静态方法,因此无论 next 对象的类是什么,都会调用它。如果此类没有重写的 equals 方法,那么肯定会使用默认的 Object.equals 。但是,如果该对象的类直接或间接重写 equals,则将使用最具体的重写。

换句话说,这段代码应该没问题(并且完全不需要强制转换)。

我建议您仔细检查是否已在相关类中正确重写了 equals 。我猜你已经将它实现为类似的东西:

public class MyFoo {
    ...
    public boolean equals(MyFoo other) {
       ...
    }
}

而参数必须是 Object 类型,否则你只是重载 equals 方法而不是覆盖它。如果您使用的是 Java 6,则可以将 @Override 注释添加到您的方法中,这将捕获此类错误。

The runtime types of the elements returned from the iterators are not (and indeed cannot be) changed. They're assigned to fields of type E, which may well be erased to Object at runtime (depending on the generic bounds) but this won't affect the objects themselves.

When equals() is invoked, it's a non-static method and so is invoked on whatever the class of the next object happens to be. If this class doesn't have an overridden equals method then sure, the default Object.equals will be used. However, if this object's class directly or indirectly overrides equals, the most specific override will be used.

In other words, this code should be fine (and the cast is completely unnecessary).

I suggest that you double-check you've overridden equals correctly in the class in question. I would guess that you've implemented it as something like:

public class MyFoo {
    ...
    public boolean equals(MyFoo other) {
       ...
    }
}

whereas the argument must be of type Object, otherwise you're just overloading the equals method instead of overriding it. If you're using Java 6, you can add the @Override annotation to your method, which will catch this sort of error.

南薇 2024-10-09 16:41:38

由于运行时多态性,equals(Object) 的正确实现将在运行时选择。你为什么认为事实并非如此?

实际上,您可能犯了一个常见错误并实现了 equals(ASpecificType) 而不是 equals(Object):您想要覆盖 equals(Object)来自 java.lang.Object 的 code> 方法。指定不同的参数类型意味着您不再重写该方法。

ASpecificType 的常见 equals() 实现可以这样开始:

public boolean equals(Object o) {
  if (this==o) {
    return true;
  } else if (o==null || o.getClass() != getClass()) {
    return false;
  }
  ASpecificType other = (ASpecificType) other;
  // insert specific comparison here
  return result;
}

The correct implementation of equals(Object) will be chosen at runtime, due to runtime polymorphism. Why do you think that's not the case?

Actually, you might have made a common mistake and implemented equals(ASpecificType) instead of equals(Object): you want to override the equals(Object) method from java.lang.Object. Specifying a different parameter type means you no longer override that method.

A common equals() implementation for ASpecificType could start like this:

public boolean equals(Object o) {
  if (this==o) {
    return true;
  } else if (o==null || o.getClass() != getClass()) {
    return false;
  }
  ASpecificType other = (ASpecificType) other;
  // insert specific comparison here
  return result;
}
挖鼻大婶 2024-10-09 16:41:38
  1. 该转换将 E 转换为 E,因此它不会执行任何操作。
  2. equals 应该无需强制转换即可工作。
  3. 正如您在评论中发布的那样, next == prev 对于偶数列表不起作用。

关于如何实现equals

public boolean equals(Object o) {
  if(this == o) { return true; }
  if(o == null) { return false; }
  if(o instanceof [ClassOfThis]) {
    o = (Type)o;
    // compare here.
  } else {
    return false;
  }
}
  1. The casting casts E to E so it doesn't do anything.
  2. equals should work without casting.
  3. As you posted in the comment, next == prev will not work for even-numbered lists.

Concerning how to implement equals:

public boolean equals(Object o) {
  if(this == o) { return true; }
  if(o == null) { return false; }
  if(o instanceof [ClassOfThis]) {
    o = (Type)o;
    // compare here.
  } else {
    return false;
  }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文