4

我有一个List(实际上是 a LinkedList),并向其中添加了实现 - 方法的项目equals

问题是我添加了相等但不相同的项目(比如两个初始化的对象)。现在,当我想获取第二个添加的项目的索引时,我当然会得到第一个项目的元素,因为indexOf搜索的是平等而不是身份。

我尝试创建自己的子类LinkedList并覆盖indexOf-method,但这是不可能的,因为我既无权访问子类Node也无权​​访问 Node-Element first

这是一个例子:

public class ExampleObject {

  int number;

  public ExampleObject(){
    number = 0;
  }

  @Override
  public boolean equals(Object obj) {
    if (this == obj) return true;
    if (obj == null) return false;
    if (getClass() != obj.getClass()) return false;
    ExampleObject other = (ExampleObject) obj;
    if (number != other.number) return false;
    return true;
  }

  public static void main(String[] args) {
    LinkedList<ExampleObject> list = new LinkedList<ExampleObject>();

    ExampleObject one = new ExampleObject();
    ExampleObject two = new ExampleObject();

    list.add(one);
    list.add(two);

    System.out.println(list.indexOf(one)); // '0' as expected
    System.out.println(list.indexOf(two)); // '0', but I want to get '1'

  }
}

我的意图:我需要一个对象列表,我想在其中存储初始化对象并稍后编辑它们。

4

2 回答 2

6

自己做迭代,indexOf只是一个辅助方法:

static int indexOfById(List<?> list, Object searchedObject) {
  int i = 0;
  for (Object o : list) {
    if (o == searchedObject) return i;
    i++;
  }
  return -1;
}
于 2013-08-02T11:28:02.773 回答
1

这个问题有几种解决方案。

1)正确的解决方案:如果您需要身份比较,那么您不应该覆盖该equals方法。你告诉我们你必须覆盖它,因为你在另一个地方需要它。这表明您的软件中存在设计问题,您确实应该解决这个问题。

2) 看看课堂sun.awt.util.IdentityLinkedList。这几乎是LinkedList该方法的身份行为的“正常” indexOf。如果您不想依赖 sun 子包中的类,可以将代码复制到位于您的包中的类中。

3)您可以按照程序解决方案自己迭代列表:

public static <E> int indexOf(List<E> list, E searchItem) {
    int index = 0;
    for (E item : list) {
        if (item == searchItem)
            return index;
        index += 1;
    }
    return -1;
}

4)为您的对象编写一个包装器。

public class IdentityWrapper {
    public Object item;
    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null) return false;
        if (getClass() != obj.getClass()) return false;
        IdentityWrapper other = (IdentityWrapper) obj;
        return item == other.item;
    }
}

然后在您的列表中使用此包装器:LinkedList<IdentityWrapper>. 请注意,我在包装器中提供了一个公共项目字段。通常,我只会使用构造函数和私有字段来完成。

于 2013-08-02T11:43:16.703 回答