【问题标题】:set.contains() and polymorphism?set.contains() 和多态性?
【发布时间】:2014-05-01 01:16:22
【问题描述】:

这感觉像是一个非常基本的问题,但它困扰着我。我想获得两组之间的差异,但似乎我无法这样做,因为该组可能包含具有不同哈希和等式实现的对象。

举一个简单的例子来说明我的问题,假设我有一个由两个类实现的 IFoo 接口,分别称为 BasicFoo 和 ExtendedFoo。它们都描述了相同的物理对象,但 ExtendedFoo 丰富了 BasicFoo 缺乏的一些额外信息。本质上 BasicFoo 描述了我的调用者感兴趣的物理对象,我最终将使用它在我的模型中查找适当的 ExtendedFoo 对象。如果 BasicFoo 描述相同的物理对象,则可以认为它们等于 ExtendedFoo。

我有一个方法可以做这样的事情:

public void removeFooInModel(HashSet<IFoo> fooColection){

   HashSet<Foo> fooInModel=Model.getFoo();
   fooCollection.removeAll(fooInModel);
   return;
}

我的问题是我认为它不会一直有效。如果用户传入一个 实际上 包含 BasicFoo 对象的 fooCollection,并且我的 Model.getFoo() 方法返回一个实际上包含 ExtendedFoo 的 Set,那么它们的 equal 和 hashCode 方法将是不同的(ExtendedFoo 有更多的状态比较是否相等)。尽管我对如何在两个对象之间映射相等性和散列有非常清楚的了解,但似乎没有办法强制我的 Set 对象使用这些知识。

我想知道的是,当我希望混合和匹配实现时,是否有任何方法可以获得 Sets 方法(如 removeAll 和 Contains)的便利性?

做到这一点的一种方法是使我的 ExtendedFoo 和 BasicFoo HashCode 方法相同,仅对 IFoo 接口中可用的状态进行散列,并通过仅比较 IFoo getter 使它们的 equal 方法比较不同类的任何 IFoo 对象方法。但是,如果我后来有人编写了一个扩展 IFoo 的 FooBar 对象,我怎么能保证他们编写与我相同的哈希码方法,所以我的方法仍然适用于他们的类?

我可以很容易地解决我自己的问题,方法是在一个地方不使用 Set,这是一个问题。但是,如果我需要 HashSet 提供的效率提升,其他人会认为“正确”的解决方案是什么?

【问题讨论】:

    标签: java set polymorphism hashset


    【解决方案1】:

    不幸的是,您无法说服哈希集比较基本对象和扩展对象是否相等,就好像它们都是基本对象一样。但是,您可以构建一个包含基本对象或扩展对象的包装对象,并使用基本对象的比较方法来比较两者。

    这是一个可能的实现的草图:

    class FooWrapper {
        private final BasicFoo obj;
        public FooWrapper(BasicFoo obj) {
            this.obj = obj;
        }
        public BasicFoo getWrapped() {
            return obj;
        }
        public int hashCode() {
            // Compute the hash code the way the BasicFoo computes it
        }
        public boolean equals(Object other) {
            // Compare the objects the way the BasicFoo does
        }
    }
    

    现在您可以获取BasicFooExtendedFoo 的混合集合,将它们包装在FooWrapper 中,然后将它们放入哈希集中。您可以对集合执行操作,然后通过从包装集合中解开单个 BasicFoo 对象来获取结果。

    【讨论】:

      猜你喜欢
      • 2010-09-30
      • 1970-01-01
      • 1970-01-01
      • 2019-09-01
      • 2014-11-11
      • 2015-06-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多