仅对相同项目进行一次索引的Java数据结构

时间:2011-05-26 23:04:13

标签: java data-structures

以下Java代码:

public static void main(String args[]) {

    int[] x = new int[] {1, 2, 3};
    int[] y = new int[] {1, 2, 3};

    LinkedList<int[]> list = new LinkedList<int[]>();

    list.add(x);

    System.out.println("List contains y: " + list.contains(y));

}

给出输出

    List contains y: false

这有意义,因为xy是对不同内存位置的引用,但是也有一种它们相同的意义(它们具有相同顺序的相同元素)。 / p>

在此示例中是否有一个数据结构会将true返回给查询list.contains(y)

6 个答案:

答案 0 :(得分:9)

我不相信有一个Java数据结构可以像true那样返回contains()

正如您可能知道的那样,问题在于,对于Java数组,equals()仅测试对象标识,而不是大多数人会定义它的“相等”。

由于contains()在这种情况下(大部分时间)都依赖于equals(),因此您会遇到给定的行为。

您必须实现专门覆盖List的{​​{1}},以便为Java数组提供所需的行为,可能使用contains()

我的建议是改为使用Arrays.equals()而不是数组;然后你有一个ListList<List<Integer>>应该适用于此方案,因为它会在底层contains()实施中使用equals()

答案 1 :(得分:2)

您需要为阵列定义比较器。然后当列表查找元素时,它将使用比较器来查看它们是否相同:

public static void main(String args []){

int[] x = new int[] {1, 2, 3};
int[] y = new int[] {1, 2, 3};

LinkedList<int[]> list = new LinkedList<int[]>(new Comparator<int[]>() {
  @Override
  public int compare(int[] a1, int[] a2) {
    if(a1 == a2) return 0;
    if(a1 == null && a2 != null) return -1;
    if(a1 != null && a2 == null) return 1;
    if(a1.size() < a2.size()) return -1;
    if(a1.size() > a2.size()) return 1;
    for(int i = 0; i < a1.size(); i++) {
      int comp = a1[i] - a2[i];
      if(comp < 0) return -1;
      if(comp > 0) return 1;
    }
    return 0;
  }
});

list.add(x);

System.out.println("List contains y: " + list.contains(y));

}

答案 2 :(得分:2)

看起来你真的在寻找Set实现。

  

不包含重复元素的集合。更正式地说,集合不包含e1e2元素对,e1.equals(e2),最多只有一个null元素。如暗示   通过它的名称,这个界面模拟数学集抽象。

如果您想存储多组int值,可以使用this Tuple class我刚才写的another question on SO

Set<Tuple> myTuples = new HashSet<Tuple>();
Tuple<Integer> x = Tuple.create(1, 2, 3);
Tuple<Integer> y = Tuple.create(1, 2, 3);

myTuples.add(x);
System.out.println("Set contains y: " + myTuples.contains(y)); // prints true

如果订单很重要,您可以使用SortedSet

答案 3 :(得分:1)

LinkedList使用equals来实现contains,因此这应该有效:

public static void main(String args[]) {
    static class Ints {
        int[] array;
        public Ints(int[] array) {
            this.array = array;
        }
        public boolean equals(Object other) {
            if (other instanceof Ints) {
                return arraysEqual((Ints) other);
            }
        }
        public boolean arraysEqual(Ints other) {
            // check that this.array and other.array are same length and
            // have same values. Do a null check somewhere too. :)
        }
    }

    Ints x = new Ints(new int[] {1, 2, 3});
    Ints y = new Ints(new int[] {1, 2, 3});

    LinkedList<Ints> list = new LinkedList<int[]>();

    list.add(x);

    System.out.println("List contains y: " + list.contains(y));

}

答案 4 :(得分:0)

您可能希望将LinkedList扩展到您自己的自定义数据结构中,并且如果您想要在标准检查之外进行任何操作,则可以定义自定义相等方法。

答案 5 :(得分:0)

如果您可以使用Set而不是数组,那么可能会更容易。看看herehere