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

时间:2009-05-20 10:18:12

标签: java algorithm data-structures oop concurrency

方案

我会尽可能简洁。基本上参考这个classdiag,我有一个管理 SocketManager (管理一个Socket连接)列表的外观。每个 SocketManager 使用唯一的 SocketUserId 登录到远程服务器。此外,每个 SocketManager 都会接受来自客户的邮件,这些邮件的目的地是收件人的特定列表。为了便于讨论,请将这些 Receipients 简单地视为由名称标识的远程数据存储区。

客户端将发送如下数据:

SocketFacade facade = ...;

byte[] data = ...

facade.sendData( receipient, data );

SocketFacade 启动时,它将查询一个mysql表,该表返回 SocketUserId Receipients 之间的1-m关系。我将使用MultiValuedMap来表示这种1米的关系。然后通过迭代地图启动多个 SocketManager

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

e.g。假设我们有2个 SocketManager ,其中 SocketUserId s“alice”&amp; “汤姆”分别

            +----SocketManager1 ( "alice" ) for Receipients { "B", "C" }
            |
 SocketFacade 
            |
            +----SocketManager2 ( "tom" ) for Receipients { "A", "D" }

问题

我正在讨论如何实现 sendData 方法。基本上我需要一种方法从收据(例如“B”)映射到其负责的 SocketManager (例如 SocketManager1 )。

让我们假设我这样做

(2) Map< SocketUserId, SocketManager >
(3) Map< Receipient, SocketUserId >
  • 我是否需要SoftReference来获取(2)中的值?
  • 我应该直接从收据映射到 SocketManager 吗?
  • SocketFacade 还支持会改变由(1)表示的关系的方法。如果我写入数据库,则(1),(2)和&amp ;;中的内存数据结构。 (3)需要同步改变。 SocketFacade 也必须是线程安全的。最初的想法是拥有某种发布订阅系统,通过这种系统,添加/删除数据库将导致更改通过回调传播。

    interface Callback
    {
        void receipientAdded( Receipient r );
        void receipientDeleted( Receipient r );
    }
    

3 个答案:

答案 0 :(得分:1)

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

SocketManager中,保留Receipient的列表。在添加和删除Receipient时,请更新指向SocketManager

的指针

SocketFacade中,您需要一张获取SocketUserId并返回SocketManager的地图。通过查询地图中的ID来填充该地图。存在所有管理员后,将收件人添加到每个管理员。这需要两个SQL查询。

使用任何ORM工具都很容易映射。

答案 1 :(得分:1)

由于SocketUserId和SocketManager之间有1-1关系,你不能只在SocketMananger中添加对SocketUserId的引用,并在收件人中添加对SocketManager的引用吗?

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

问候

纪尧姆

答案 2 :(得分:1)

在抽象级别,您有:1 Thing与n OtherThing相关。您可以通过创建一个特殊关系对象来对此进行建模,该对象引用Thing并包含对java.util.List<OtherThing> s的OtherThing个引用。这使您的域对象(Things)整洁有关系信息。但是如果它看似正确,那么将java.util.List直接添加到类Thing(或子类)就更简单了。只有在需要建立关系时,List变量才能保留为空并填充java.util.ArrayList<OtherThing>