有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

二进制关系的java接口

我想为二元关系和传递关系定义优雅的接口。我认为二元关系是一组对,一组x×y的子集。事实上,我打算主要用传递关系来工作,但我偶尔需要一般的二元关系。这主要是供我自己使用,但我可能最终会将其作为FLOSS库发布给其他用户。我希望我的定义在一般层面上有意义,因为我还没有关于这些课程使用的精确要求:我需要它们用于与科学研究相关的实验工作,我现在有一些想法,但还不清楚我需要什么样的实验,因为在做研究时会有更多的想法

总体思路

我(认为我)需要的核心如下

/**
 * @param <F>
 *            the type used for the “from” elements.
 * @param <T>
 *            the type used for the “to” elements.
 * 
 */
public interface BinaryRelationTentative<F, T> {
    /**
     * @return a view of the domain of this relation: all the elements x such that for some y, (x, y) is in the
     *         relation.
     */
    public Set<F> getFromSet();

    /**
     * @return a view of the range of this relation: all the elements y such that for some x, (x, y) is in the relation.
     */
    public Set<T> getToSet();

    /**
     * @return the number of pairs that this relation contains.
     */
    public int size();

    /**
     * @return <code>true</code> iff the relation has empty from and to sets.
     */
    public boolean isEmpty();

    /**
     * A binary relation equals an other one iff they have equal from and to sets and for each (x, y) contained in one,
     * (x, y) is contained in the other one.
     */
    @Override
    public boolean equals(Object obj);

    /**
     * @return whether the given <code>from</code> element is in relation with the <code>to</code> element.
     */
    public boolean contains(F from, T to);

    /**
     * Optional operation.
     */
    public boolean add(F from, T to);
}

(这只是核心特性,因此您可以理解我的意思-更好的遍历等特性是受欢迎的,请参见下文。)然后我将定义一个扩展BinaryRelation<E, E>TransitiveRelation<E>,它不实现add,而是提供addTransitive(F from, T to)

重复使用经典藏品

当然,我希望尽可能地重用经典集合接口。看起来番石榴的SetMultimapjavadocuser guide)具有我需要的核心功能和更多功能。用户指南甚至提到了未标记有向图的用例。我看到直接使用SetMultimap的一个问题是术语并不完全正确:在二进制关系中提到“键”和“值”是很奇怪的。此外,它还遗漏了一些东西。在SetMultimap(设计为从键到值)中存在一种不对称性,而在二进制关系中则没有这种不对称性。SetMultimap有一个接口(和实现),它允许给定一个“from”元素,通过与之相关的“to”元素高效地迭代(即不遍历整个关系)。类似地,我希望能够使用“to”元素,高效地迭代相应的“from”元素。所以我需要一个叫做BiSetMultimap的东西(对应于aMap<K, Set<V>>和aMap<V, Set<K>>)。我在Java世界中还没有找到这样的东西

因此,我目前正在考虑将BinaryRelation<F, T>定义为facadeSetMultimap<F, T>。然后,我可以在接口中创建更好的命名方法(概念上等同于SetMultimap中的方法),并且可以添加一个方法getInverselyRelated(T to): Set<F>,该方法给出“from”元素。我可以提供基于两个保持同步的SetMultimap的实现,一个表示关系,另一个表示其逆关系

对于这个问题有很多替代方法。例如,我可以将BinaryRelation定义为扩展SetMultimap。或者我可以避免完全隐藏SetMultimap,并通过BinaryRelation#asSetMultimap()提供对它的访问。这样我就得到了他们所有漂亮的方法接口。或者我可以完全放弃特定接口的想法,使用SetMultimap而不是BinaryRelation,然后将反向遍历操作视为特定类中可用的优化功能,但不在接口级别。或者我可以使用SetMultimap以外的其他东西作为设计的基础

因此,我的问题(最后!):你觉得我的方法怎么样?你能考虑其他方法吗?我忽略了一些问题?我可以使用的现有解决方案

可能的联系

我曾考虑使用一些图形库(JUNGJGraphTBlueprint),但我认为它们不适合我的需要。所有这些都有一个Edge类(或边缘类型参数),这增加了复杂性,在我看来,没有一个提供的接口和实现比SetMultimap更好Grph并不像user manual所说的那样,为顶点提供对象。我可能错过了一些东西,如果你不同意,请告诉我

(编辑)正如Xaerxess所提到的,这个番石榴issue建议在番石榴上添加我在这里称之为BiSetMultimap的东西


共 (1) 个答案

  1. # 1 楼答案

    听起来像是早期优化:为什么不在内部使用两个数据结构(问题中提到的Map<K, Set<V>>Map<V, Set<K>>)。当有最直接的方法存在实际问题时,你可以考虑不知名的图书馆或番石榴,但同时你可以在工作的其他方面取得进展。毕竟,接口的主要目的是隐藏底层实现,以便以后可以对其进行更改