如何在Java中实现n:m关系? [英] How to implement n:m relation in Java?

查看:321
本文介绍了如何在Java中实现n:m关系?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在Java中实现n:m关系。
用例是一个目录。




  • 一个产品可以有多个类别

  • 一个类别可以容纳多个产品



我现在的解决方案是有一个有两个hashmaps的映射类。




  • 第一个hashmap的关键是产品id,值是类别id的列表
  • 第二个hashmap是类别id,值是产品id的列表



这是完全多余的,我需要一个始终如一的设置类在这两个hashmaps中保存/删除数据。



但是,这是我发现在 O(1)中创建以下性能的唯一方法


  • 什么产品可以包含某个类别?

  • 产品包含哪些类别?



我想避免全阵列扫描或其他任何方式。



但是,必须有另一个更优雅的解决方案在哪里我不需要索引数据两次。



请点亮我。我只有普通的Java,没有数据库或SQLite或可用的东西。如果可能的话,我也不太想实现一个btree结构。如果您通过成员集合将Categories与Products关联起来,然后你可以完成同样的事情:

  public class Product {
private Set< Category> categories = new HashSet< Category>();
//实现hashCode和equals,可能通过id来获得额外的性能
}

public class Category {
private Set< Product> contents = new HashSet< Product>();
//实现hashCode和equals,可能通过id获得额外的性能
}

唯一困难的部分是填充这样的结构,可能需要一些中间映射。

但是使用辅助hashmaps / trees进行索引的方法并不差。毕竟,放在数据库上的大多数索引都是辅助数据结构:它们与行表共存;行不一定组织在索引本身的结构中。

使用这样的外部结构可以让您保持优化和数据彼此分离;这不是一件坏事。特别是,如果明天你想为给定供应商的产品添加O(1)查找,例如

编辑:方式,它看起来像你想要的是 Multimap 也进行了优化,以便在O(1)中进行反向查找。我不认为Guava有这样的功能,但是你可以实现Multimap接口,所以至少你不必分别处理HashMap的处理。实际上它更像是一个BiMap,它也是一个Multimap鉴于其定义,这是矛盾的。我同意MStodd的看法,您可能想要推出自己的抽象层来封装两张地图。


I need to implement an n:m relation in Java. The use case is a catalog.

  • a product can be in multiple categories
  • a category can hold multiple products

My current solution is to have a mapping class that has two hashmaps.

  • The key of the first hashmap is the product id and the value is a list of category ids
  • The key to the second hashmap is the category id and the value is a list of product ids

This is totally redundant an I need a setting class that always takes care that the data is stored/deleted in both hashmaps.

But this is the only way I found to make the following performant in O(1):

  • what products holds a category?
  • what categories is a product in?

I want to avoid full array scans or something like that in every way.

But there must be another, more elegant solution where I don't need to index the data twice.

Please en-light me. I have only plain Java, no database or SQLite or something available. I also don't really want to implement a btree structure if possible.

解决方案

If you associate Categories with Products via a member collection, and vica versa, then you can accomplish the same thing:

public class Product {
     private Set<Category> categories = new HashSet<Category>();
     //implement hashCode and equals, potentially by id for extra performance
}

public class Category {
     private Set<Product> contents = new HashSet<Product>();
     //implement hashCode and equals, potentially by id for extra performance
}

The only difficult part is populating such a structure, where some intermediate maps might be needed.

But the approach of using auxiliary hashmaps/trees for indexing is not a bad one. After all, most indices placed on databases for example are auxiliary data structures: they coexist with the table of rows; the rows aren't necessarily organized in the structure of the index itself.

Using an external structure like this empowers you to keep optimizations and data separate from each other; that's not a bad thing. Especially if tomorrow you want to add O(1) look-ups for Products given a Vendor, e.g.

Edit: By the way, it looks like what you want is an implementation of a Multimap optimized to do reverse lookups in O(1) as well. I don't think Guava has something to do that, but you could implement the Multimap interface so at least you don't have to deal with maintaining the HashMaps separately. Actually it's more like a BiMap that is also a Multimap which is contradictory given their definitions. I agree with MStodd that you probably want to roll your own layer of abstraction to encapsulate the two maps.

这篇关于如何在Java中实现n:m关系?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆