如何选择合适的java数据结构来建模1-n关系映射?

如何选择合适的java数据结构来建模1-n关系映射?,java,algorithm,data-structures,oop,concurrency,Java,Algorithm,Data Structures,Oop,Concurrency,场景 我将尽可能简洁。基本上,关于这一点,我有一个facade,它管理一个SocketManager列表(它管理一个套接字连接)。每个SocketManager都使用唯一的SocketUserId登录到远程服务器。此外,每个SocketManager将接受来自特定接收者列表的客户端的消息。为便于讨论,请考虑这些“强>收件人< /St>”,简单地称为名称标识的远程数据桶。 客户端将发送如下数据: SocketFacade facade = ...; byte[] data = ... faca

场景

我将尽可能简洁。基本上,关于这一点,我有一个facade,它管理一个SocketManager列表(它管理一个套接字连接)。每个SocketManager都使用唯一的SocketUserId登录到远程服务器。此外,每个SocketManager将接受来自特定接收者列表的客户端的消息。为便于讨论,请考虑这些“强>收件人< /St>”,简单地称为名称标识的远程数据桶。

客户端将发送如下数据:

SocketFacade facade = ...;

byte[] data = ...

facade.sendData( receipient, data );
当SocketFacade启动时,它将查询一个mysql表,该表返回SocketUserId和Receipements之间的1-m关系。我将使用a来表示这种1-m关系。然后,通过迭代映射启动多个SocketManager

(1) Map< SocketUserId, List<Receipient> > 
问题

我对如何实现sendData方法感到困惑。基本上,我需要一种从接收者(例如“B”)映射到其负责的SocketManager(例如SocketManager 1)的方法

让我们假设我这样做

(2) Map< SocketUserId, SocketManager >
(3) Map< Receipient, SocketUserId >

在每个
收件人中保留对
SocketManager
的引用。这样,您可以避免映射(需要更多的RAM,速度较慢,并且不会增加任何值)

SocketManager
中,保留一个
接收者的列表。在添加和删除
接收器时,请更新指向
SocketManager
的指针

SocketFacade
中,需要一个映射,该映射采用
SocketUserId
并返回
SocketManager
。通过查询映射中的ID来填充该映射。存在所有管理器后,将收件人添加到每个管理器中。这需要两个SQL查询


这很容易与任何ORM工具进行映射。

既然SocketUserId和SocketManager之间存在1-1关系,您就不能在SocketManager中添加对SocketUserId的引用,并在收件人中添加对SocketManager的引用吗

然后,您将在facade中有一个包含收件人和SocketManager列表的映射。在
sendData
函数中,您将从映射中获取收件人,并从该收件人获取对其SocketManager的引用

问候


纪尧姆

在抽象的层次上,你有:1
事物
与n
其他事物
s相关。您可以通过创建一个特殊的关系对象对其进行建模,该对象引用
Thing
,并包含一个
java.util.List
对n
OtherThing
s的引用。这会使您的域对象(事物)与关系信息保持一致。但是,如果它看起来是正确的,那么直接将
java.util.List
添加到类
Thing
(或子类)就更简单了。只有在需要建立关系时,列表变量才可以保留为null,并使用
java.util.ArrayList
填充。

SocketManager一开始会被粘贴到映射中,因为它下面运行两个线程和一个套接字通道。我计划保留一个列表,这样我就可以方便地迭代并调用shutdown。你怎么认为?是,SocketManager将引用SocketUserId(1-1)。既然一个收件人只与一个SocketManager相关,为什么我需要SocketManager的列表?根据您的想法,我只需要Map。我没听错吧?@ashitaka:嗯?根据您的示例,SocketManager对收件人的比率为1:N@我犯了一个错误。我的意思是“因为一个SocketUserId只与一个SocketManager相关……”。SocketManager对收件人的比率为1:NYes。从我的观点来看,SocketManager的列表并不是绝对必要的,但正如您所说的,您可能需要管理SocketManager(启动、停止、获取当前状态、获取一些流量信息…),在我看来,将SocketManager放入收件人中不是很好。然后,接收者将SocketManager公开给SocketFacade的客户机/调用方。这背后的问题是“接收者是否需要知道哪个SocketManager对他负责。”。就我对这个场景的理解而言,这不是我想要的,应该隐藏在门面后面。这只是门面设置的问题。到目前为止我做得对吗?基本上,我希望将提供给SocketFacade的消息发送到正确的SocketManager。仅此而已。收件人由字符串标识符标识。另一个设计标准是能够添加和删除由特定SocketManager处理的接收器(这涉及内存中的更改和数据库更新)。为了回答你的问题,理想情况下,接收者不需要知道它与什么SocketManager有关。@rudolfson:啊,那么我误解了。我认为这就像“向SocketManager的所有收件人发送消息”。嗯。回到绘图板上。它是“接收者”,而不是“接收者”。代码中的拼写错误是令人讨厌的bug来源。
(2) Map< SocketUserId, SocketManager >
(3) Map< Receipient, SocketUserId >
interface Callback
{
    void receipientAdded( Receipient r );
    void receipientDeleted( Receipient r );
}