4

I have a tabular data representation in Java. So far, I am using Google Guava to hold the data within an Table<R,C,V>.

Given this table

|----------------------------------------------|
| Artist          | Genre    | Type            |
|----------------------------------------------|
| Eddie Van Halen | Musician | Hard Rock       |
| David Bowie     | Musician | Art Pop         |
| David Lynch     | Director | Surrealist Film |
| George Lucas    | Director | Blockbuster     |
|----------------------------------------------|

I use this

Table<String, String, String> table = HashBasedTable.create();
table.put("Eddie Van Halen", "Genre", "Musician");
table.put("Eddie Van Halen", "Type",  "Hard Rock");

table.put("David Bowie", "Genre", "Musician");
table.put("David Bowie", "Type",  "Art Pop");

table.put("David Lynch", "Genre", "Director");
table.put("David Lynch", "Type",  "Surrealist Film");

table.put("George Lucas", "Genre", "Director");
table.put("George Lucas", "Type",  "Blockbuster");

to create the table object.

It is very easy to get data by using row or colum keys. So I might get the genre of David Bowie:

table.get("David Bowie", "Genre"); // "Musician"

Also I can get all data of a particular column:

table.column("Genre").values(); // [Musician, Director, Musician, Director]

My main interest is to retrieve all artists, who are directors. In this case it is a lookup by value. There are two dimensional Maps out there like BidiMap from Apache Collections or BiMap from Google Guava.

But are there implementations that help to get a Set of row keys by value of tabular data?

I would love to find something like

Set<R> table.getRowsByValue( C columnKey, V value )

This should result in something like:

table.getRowsByValue("Genre", "Musician"); // [David Bowie, Eddie Van Halen]

Update 1

As I mentioned before, there are Map implementations, that allow to retrieve a key by a given value.
I tried to use them:

    BidiMap bidiMap = new DualHashBidiMap<String,String>(table.column("Genre")); 
    bidiMap.getKey("Musician"); // "David Bowie"

The Apache Colletions way - only the last element will be returned.

    BiMap biMap = HashBiMap.create(table.column("Genre"));
    biMap.inverse().get("Musician");

BiMap of Google Guava throws an (verbose) exception:

java.lang.IllegalArgumentException: value already present: Musician
jwrangel
  • 93
  • 5
  • 2
    AFAIK, you'll have to iterate –  Dec 04 '15 at 12:13
  • By the way hash tables work you are not suppossed to ask your kind of questions. You have a key and a value. You can find a value by its key. You can not find a key by its value. If you want it to work both ways, you have to create a second table where key and value are swapped or an index by for example using a `HashMap` with your type as key and artist as value. – Aracurunir Dec 04 '15 at 12:23
  • Would that not be a perfect example for an in memory database? – pandaadb Dec 04 '15 at 13:14
  • 1
    Also possible duplicate http://stackoverflow.com/questions/8066109/bidirectional-multi-valued-map-in-java – Yosef Weiner Dec 04 '15 at 13:15

1 Answers1

0

With a regular map, I would have iterated Map.entrySet(), then pull Map.Entry.getKey().

Here you seem to be able to iterate cellSet() which returns Set<Table.Cell<R,C,V>>

in java 8 (hopefully no typos, I didn't try):

table.cellSet().stream()
   .filter(tc -> tc.getColumnKey().equals("Director"))
   .collect(Collectors.toList());
user2023577
  • 1,752
  • 1
  • 12
  • 23