0

I need a hashmap solution whereby the key is an Investor Object that is unique, and value is a Portfolio object.

The problem is that I need Investors to be sorted by their Portfolio Object, which has a total Value inside, which is changing constantly as he/she buys/sells stocks.

How can one solve this issue? thanks!

delita
  • 1,571
  • 1
  • 19
  • 25
  • 2
    see this http://stackoverflow.com/questions/109383/how-to-sort-a-mapkey-value-on-the-values-in-java – Anish Dasappan Nov 08 '11 at 11:15
  • Actually, I don't think the above will work well since I believe the TreeMap only sorts on insertion. – John B Nov 08 '11 at 11:43
  • So, how do you need to get the Portfolios? Do you just need to get a sorted list of Portfolios or do you need to iterate the Map (key and value) in order by Portfolio value? – John B Nov 08 '11 at 11:47
  • At the moment, i only need to know who is my top investor with the largest portfolio value. Hence i need the map sorted.... – delita Nov 08 '11 at 11:57
  • Given that, I think doing something similar to a combination of Anish post and my answer is probably best. Create a method that will sort the values (or entries) in the Map and return the sorted list (SortedSet) or the first / last entry. Just ensure that the data doesn't change during the sort process. ;) – John B Nov 08 '11 at 12:06

3 Answers3

1

Depending on your requirements, I think the best solution is to store the values in a standard Map but provide a method to get the Portfolios in order ImmutableSortedSet<Portfolio> getSortedPortfolios(). The method would get the list of values and put them in the Set. This assumes that Portfolios implements Comparable otherwise you would need to provide a Comparator.

ImmutableSortedSet<Portfolio> getSortedPortfolios(){
   return ImmutableSortedSet.builder()
             .addAll(myMap.getValues())
             .build();
}

If you really need thread-safety I would recommend using a copy-constructor to create snapshots and insert them. This would ensure that the returned sorted list remains sorted.

ImmutableSortedSet<Portfolio> getSortedPortfolios(){
   ImmutableSortedSet.Builder<Portfolio> builder = ImmutableSortedSet.builder();

   for (Portfolio p : myMap.getValues()){
      builder.add(new Portfolio(p));
   }

   return builder.build();
}

I am using Guava's ImmutableSortedSet here, but you could just use a SortedSet and treat it as immutable or use Collection.unmodifiable...

John B
  • 32,493
  • 6
  • 77
  • 98
1

The problem is that I need Investors to be sorted by their Portfolio Object, which has a total Value inside, which is constantly as he/she buys/sells stocks.

The "constantly changing" is the tricky part here.

AFAIK, is no efficient (i.e. O(logN) or better performance) data structure that can keep something sorted on a constantly changing value. All general purpose map API's I've come across assume that keys don't change while a mapping is a member of the map.

So, what I think you will have to use an event mechanism to track "change of value" events for the Portfolio object. The event handler would need to atomically remove the Portfolio from the ordered mapping, make the change, and then add it back in again at the new position.

To implement the data structures you need either a pair of maps or a bidirectional map.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
0

As far as I know, Java collection library does not have a data structure to suit your requirement. But you can use TreeBidiMap in the common collection library

Upul Bandara
  • 5,973
  • 4
  • 37
  • 60
  • Wouldn't the TreeBidiMap have to resort the tree whenever a value changed? Is it able to do this? – Robert Nov 08 '11 at 11:47