Java 二进制关系接口

Java 二进制关系接口,java,interface,guava,digraphs,Java,Interface,Guava,Digraphs,我想为二元关系和传递关系定义优雅的接口。我认为二元关系是一组对,一组x×y的子集。事实上,我打算主要用传递关系来工作,但我偶尔需要一般的二元关系。这主要是供我自己使用,但我可能最终会将其作为FLOSS库发布给其他用户。我希望我的定义在一般层面上有意义,因为我还没有关于这些课程使用的精确要求:我需要它们用于与科学研究相关的实验工作,我现在有一些想法,但还不清楚我需要什么样的实验,因为在做研究时会有更多的想法 总体思路 我(认为我)需要的核心如下 /** * @param <F> *

我想为二元关系和传递关系定义优雅的接口。我认为二元关系是一组对,一组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);
}
(这只是核心特性,因此您可以理解我的意思-欢迎使用更好的遍历等特性,请参见下文。)然后我将定义一个扩展
二进制关系的
transitionrelation
,它不实现
add
,而是提供
addTransitive(F from,T to)

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

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

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

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

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


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

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

可能需要在代码审阅中发布。请参阅并使用Guava中的BiMultimap(它在Google内部实现,但尚未开源)。再次思考我的问题,我现在想知道这是否是一个好问题。1.我(有点)回答我自己的问题(通过提出一些初步设计);2.可能没有办法精确地回答这个问题,因为这个问题本身并不精确。OTOH,提到Xaerxess(间接地)确实是对我的问题的回答,我很乐意接受。你怎么看?嗯,最直接的方法有一些问题。我实际上是从实现传递关系的天真版本开始的。事实证明,以一种非荒谬的低效方式实现它并不那么容易。如果真的有一个有效的传递关系实现,我会节省使用它的时间。在哪种情况下,传递关系的效率会低得可笑?另外,为什么要为传递关系添加新的
addTransitive()
方法?如果关系显式是可传递的,那么在不考虑可传递性的情况下,
add()
如何解释呢?我的意思是我最初的实现(没有使用您的建议)效率低下。至于使用映射到集合的映射,这是exac