Java:要在充满自定义对象的 ArrayList 中使用包含,我应该覆盖 equals 还是实现 Comparable/Comparator?

标签 java collections equals comparator comparable

我有一个包含这些的 ArrayList:

class TransitionState {

    Position positionA;
    Position positionB;

    int counter;

    public boolean equals (Object o){

        if (o instanceof TransitionState){

          TransitionState transitionState= (TransitionState)o;

          if ((this.positionA.equals(transitionState.positionA))
                  &&(this.positionB.equals(transitionState.positionB)))
          {
              return true;
          }
        }
     return false;

    }

    @Override
    public String toString() {

        String output = "Position A " + positionA.i+ " "+ positionA.j + " "+ positionA.orientation + " "+
                "Position B " + positionB.i + " "+ positionB.j + " "+ positionB.orientation;

        return output;
    }

}

class Position {

    int i;
    int j;
    char orientation;

    Position() {

    }


    void setIJ(int i, int j){
        this.i=i;
        this.j=j;
    }

    void setOrientation(char c){

        orientation = c;
    }

   public boolean equals(Object o){

        if(o instanceof Position){

          Position p = (Position)o;
          if((p.i==this.i)&&(p.j==this.j)&&(p.orientation==this.orientation))
          {
              return true;
          }
              else return false;

        }

            return false;
   }

} //end class Position

我用这个查询:

 if(!transitionStatesArray.contains(newTransitionState)){  //if the transition state is new add and enqueue new robot positions

                 transitionStatesArray.add(newTransitionState); //marks as visited

我在我的 transitionStatesArray 中发现了重复的元素,这是为什么?

我正在使用这些 i、j 和方向值来填充矩阵中的唯一值,但这里我有一个副本:

 S  .  N 
 *  *  * 
 .  D  D 


 E  .  O 
 *  *  * 
 .  D  D 


 N  .  S 
 *  *  * 
 .  D  D 


 S  .  N 
 *  *  * 
 .  D  D 

最佳答案

List.contains(...) 方法被定义为使用 equals(Object) 来决定参数对象是否被列表“包含”。所以你需要重写 equals ...假设默认实现不是你需要的。

但是,您需要注意 List.contains(...) 可能会针对列表中的每个元素测试参数。对于一长串,这是昂贵的。根据您的应用程序的详细信息,使用不同的集合类型(例如 HashSetTreeSetLinkedHashSet)可能会更好) 而不是 List。如果您使用其中之一,您的类将需要覆盖 hashCode 或实现 Comparable,或者您将需要创建一个单独的 Comparator .. . 取决于您的选择。


(关于替代方案的更多建议......因为 OP 很感兴趣)

containsList 类型(如 ArrayListLinkedList 上)的性能是 O(N )contains 调用的最坏情况成本与列表长度成正比。

对于 TreeSetcontains 的最坏情况性能与 log2(N) 成正比。

对于HashSetLinkedHashSetcontains的平均性能是一个常数,与集合的大小无关,但最差-案例性能为 O(N)。 (如果您 1)实现一个糟糕的 hashcode() 函数,将所有内容散列为少量值,或者 2)调整“加载因子”参数,则出现最坏的性能,以便散列表不'随着它的增长自动调整大小。)

使用 Set 类的缺点是:

  • 它们是集合;也就是说,您不能将两个或多个“相等”的对象放入集合中,并且
  • 它们不能被索引;例如没有 get(pos) 方法,并且
  • 一些 Set 类甚至不保留插入顺序。

在决定使用什么集合类时需要考虑这些问题。

关于Java:要在充满自定义对象的 ArrayList 中使用包含,我应该覆盖 equals 还是实现 Comparable/Comparator?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5907259/

相关文章:

java - Guava 的 Multimaps 类的 index() 函数内部是如何工作的?

Java 字符串不等于

java - 一致的 Equals() 结果,但不一致的 TreeMap.containsKey() 结果

java - Kafka Streams KTable 外键连接无法按预期工作

java - 如何用数组进行减法/除法

java - Collections.singleton 作为静态工厂方法的实现

collections - 使用 jekyll/liquid 如何获取 yaml 哈希的所有键

jquery - "="登录 JSON 文本导致解析错误

java - 通过交集类型附加约束的通用参数

java - 在底部的向下箭头上向 jTable 添加一行