实现签名冲突的多个接口

时间:2020-03-05 18:55:30  来源:igfitidea点击:

最后,我尝试用Java实现混合结构,如下所示:

public class MapOfSet<K, V extends HasKey<K>> implements Set<V>, Map<K, Set<V>>

其中HasKey是以下接口:

public interface HasKey<K> {
    public K getKey();
}

不幸的是,在Java中,Set接口的方法签名和Map接口之间存在一些冲突。我最终选择仅实现Set接口,并添加Map方法而不实现此接口。

我们看到更好的解决方案了吗?

针对第一个评论,这是我的目标:

Have a set structure and be able to efficiently access to a subset of values of this set, corresponding to a given key value.
  At the beginning I instantiated a map and a set, but I tried to joined the two structures to optimize performances.

解决方案

回答

我要说的是,有时可以用作Map,有时用作Set的东西应该实现Map,因为可以将其视为一组键或者值以及键和值之间的映射。那就是Map.containsKey()和Map.containsValue()方法的作用。

回答

你想达到什么目的? Map已经通过其[keySet()]将其键公开为Set了(http://java.sun.com/j2se/1.5.0/docs/api/java/util/Map.html#keySet( )) 方法。如果我们需要可靠的迭代顺序,则可以使用LinkedHashMap和TreeMap。

更新:如果我们想确保一个值仅被插入一次,则可以扩展上面提到的类之一,以创建诸如" SingleEntryMap"之类的内容,并将" put(K key,V value)"的实现覆盖进行唯一性检查并在值已插入时引发Exception。

更新:这样的事情会工作吗? (我没有编辑器,因此可能无法编译)

public final class KeyedSets<K, V> implements Map<K,Set<V>> {
    private final Map<K, Set<V>> internalMap = new TreeMap<K, Set<V>>;
    // delegate methods go here
    public Set<V> getSortedSuperset() {
        final Set<V> superset = new TreeSet<V>();
        for (final Map.Entry<K, V> entry : internalMap.entrySet()) {
            superset.addAll(entry.getValue());
        }
        return superset;
    }
}

回答

也许我们可以添加更多信息,我们真正想要什么操作。我想我们想创建一个集合,该集合可以通过键自动将其元素分组,对吗?问题是我们想进行哪些操作?如何将元素添加到集合中?可以通过从分组视图中删除元素来删除它们吗?我的建议是这样的接口:

public interface GroupedSet<K, V extends HasKey<K>> extends Set<V>{
    Set<V> havingKey(K k);
}

如果我们希望能够使用"设置为地图",则可以添加另一种方法

Map<K,Set<V>> asMap();

这样可以避免使用多个接口继承以及由此产生的问题。