New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Mutable BiMultimap #394
Comments
Original comment posted by jim.andreou on 2010-08-10 at 10:10 PM In other words, (and assuming you want to access the relationships bidirectionally,) you look for a BiMultimap<K, V>. For reference, this is the API surface that BiMap takes: In the meantime, it can't be that hard to maintain a Multimap<K, V> along with the inverse Multimap<V, K>, if offer just a tiny API for updates. It would be a mess if you wanted to expose these as mutable multimaps to users - you would have to wrap them in ForwardingMultimaps and intercept all kind of methods, returning ForwardingXXX (key sets, values, iterators...). This is a big implementation investment. Much simpler if you only expose unmodifiable Multimaps, and have just one method that does the updates (perhaps its inverse too). For another reference, here is the API I designed for many-to-many relations by the way (not for your case, only meant for transitive relations) - it was easy to offer bidirectionality with only a couple of methods for updates, not the myriads of ways a Map or a Multimap can be updated. |
Original comment posted by Lord.Quackstar on 2010-08-21 at 03:52 PM @jim.andreou I think this is such a unique problem that implementing ForwardMultimaps and Multimaps would just make a mess of code. A simpler independent class thats would be mutable is a much more viable alternative, and would actually get people to write the initial code One way to implement this is have 2 HashMaps with HashSets as their values. One map would be for keys and one map would be for values. This is how it would work Definition Requirements Examples How long would such a thing take? |
Original comment posted by boppenheim@google.com on 2010-09-23 at 05:09 AM I could actually use something like this in some code I'm writing (outside of Google). It does, however, seem like it could be the type of thing that will take a lot of work to get right (in terms of both performance and corectness). |
Original comment posted by Lord.Quackstar on 2010-09-23 at 11:43 AM @boppenheim I do have a simple implementation that I wrote here: http://code.google.com/p/pircbotx/source/browse/trunk/src/main/java/org/pircbotx/ManyToManyMap.java If you want, you can use it. Its pretty basic, not worrying about iterators or merged datasets. Just copy and go. |
Original comment posted by jim.andreou on 2010-09-23 at 07:42 PM @LordQuackstar, a simple implementation is pretty trivial to do, designing and supporting the most useful API is not :) btw, you forgot to synchronize a couple of methods (removeA, removeB). |
Original comment posted by boppenheim@google.com on 2010-09-23 at 08:09 PM Thanks for letting me know about your implementation. Thankfully in my application, I never need to take the map as an argument, return it from a method, or do anything fancy; it's completely private to one class. So for my use, two maps is okay. |
Original comment posted by fry@google.com on 2011-01-28 at 04:59 PM (No comment entered for this change.) Status: |
Original comment posted by kevinb@google.com on 2011-07-13 at 06:18 PM (No comment entered for this change.) Status: |
Original comment posted by fry@google.com on 2011-12-10 at 03:47 PM (No comment entered for this change.) Labels: |
Original comment posted by wasserman.louis on 2012-01-10 at 04:15 PM Does the new inverse() method in ImmutableMultimap help? |
Original comment posted by fry@google.com on 2012-02-16 at 07:17 PM (No comment entered for this change.) Status: |
Original comment posted by kevinb@google.com on 2012-05-30 at 07:43 PM (No comment entered for this change.) Labels: - |
Original comment posted by kevinb@google.com on 2012-06-22 at 06:16 PM (No comment entered for this change.) Status: |
Original comment posted by knightofiam on 2013-02-24 at 09:22 PM I would like to see this implemented because I am looking for a one-to-many bidirectional multimap, which is a special case. There is already a request for this in the guava forums, which also links back to this issue. See: https://groups.google.com/forum/?fromgroups=#!topic/guava-discuss/K0edXSa3k7A ImmutableMultimap.inverse() doesn't work well for me because I have to do something ugly like:
where countriesInContinent is an ImmutableMultimap <Continent, Country>. I don't want to store a continent reference inside of a Country because I don't want Countries to need to know about Continents. ImmutableMultimap.inverse() could work if there was a way to guarantee only unique values in the multimap, thus allowing the return type of the inverse method to be a simple map rather than a multimap. |
Original comment posted by cpovirk@google.com on 2013-02-25 at 12:56 AM If you can build the Country->Continent mapping first and if you can wait for release 14 (or use 14.0-rc3), you can this: ImmutableMap<Country, Continent> continentForCountry = ...; |
Original comment posted by knightofiam on 2013-02-25 at 05:27 PM That's ingenious. Thanks! |
Original comment posted by greg.briggs on 2013-05-13 at 11:08 PM My application could make use of a mutable bidirectional multimap. Note that, compared to Multimap, I would suggest using Set instead of Collection, for reverse lookup to make sense. In other words, I am hoping for a BiMultimap that would replace this pair of variables: Map<X,Set<Y>> forward; Also, a total count of all the X-Y pairs would be great. Thanks! |
Original comment posted by xaerxess on 2014-07-27 at 09:18 AM Any chance of open-sourcing BiMultimap? There's some demand for it (26 stars, also see this SO question: http://stackoverflow.com/questions/24850359/bidirectional-multimap-equivalent-data-structure). Maybe you should release BiMulimaps only with BiMultimapBuilder, but without "standard" implementations? |
Original comment posted by kevinb@google.com on 2014-07-27 at 05:38 PM The star count and the SO post tell us nothing about how many users actually need mutability. The closest I see to that is comment 18 declaring "we could make use of it." Unless we get clear evidence of a widespread need that ImmutableMultimap.inverse() won't satisfy, adding this feature would be a betrayal of Guava's focus on "power-to-weight ratio". Status: |
Original issue created by Lord.Quackstar on 2010-08-10 at 08:54 PM
One of the things that would be extremely helpful in a project of mine is a map with a Many to Many relationship. Currently all that exists is a one to many relationship with the MultiMap
For those who have no idea what I'm talking about, consider this example (from Wikipedia): You want to store Authors of books and the actual books in a map. A book can be written by many authors, and authors can write many books. The only workaround is a custom undocumented class that tries to keep all the associations in several maps. In most cases it can lead to bad performance or subtle bugs that the author didn't notice when quickly writing out the class.
If there was an open source and documented implementation out there, this would help out many people. For speed it should probably be backed a HashMap and HashSet, and for people using this in a multithreaded environment it should be able to be wrapped in a synchronized class.
Could such a Map be created?
The text was updated successfully, but these errors were encountered: