brainydexter
brainydexter

Reputation: 20356

how can I filter map entries based on set of entries

I'm using google guava 12 and have a map:

Map<OccupancyType, BigDecimal> roomPrice;

I have a Set:

Set<OccupancyType> policy;

How can I filter entries in the roomPrice map based on policy and return the filtered map ?

filteredMap needs to have all the values from policy. In case, roomPrice map doesnt have an entry from policy, I'd like to input default value instead.

Upvotes: 9

Views: 16564

Answers (3)

tkruse
tkruse

Reputation: 10685

No need to use Guava, also Maps.filterKeys() can produce a result with very bad performance for large Maps.

// (new map can be initialized to better value to avoid resizing)
Map<OccupancyType, BigDecimal> filteredMap = new HashMap<>(roomPrice.size());
for (OccupancyType key: policy) {
    // contains() and get() can usually be combined
    if (roomPrice.contains(key)) {
       filteredMap.put(key, roomPrice.get(key));
    }
}

Upvotes: 0

Francisco Paulo
Francisco Paulo

Reputation: 6322

Since you have a Set of keys you should use Maps.filterkeys(), also Guava provides a pretty good set of predicates that you can use out of the box. In your case something like Predicates.in() should work.

So basically you end up with:

Map<OccupancyType, BigDecimal> filteredMap
    = Maps.filterKeys(roomPrice, Predicates.in(policy));

Hope it helps.

Upvotes: 29

Jeshurun
Jeshurun

Reputation: 23186

  • Override and implement equals and hashcode in OccupancyType.
  • Loop through roomPrice's keyset and collect the elements contained in the filter.

Something like this:

Map<OccupancyType, BigDecimal> filteredPrices = new HashMap<OccupancyType, BigDecimal>();
for(OccupancyType key : roomPrice.keySet()) {
    if(policy.contains(key) {
        filteredPrices.put(key, roomPrice.get(key));
    }
}

Update

Ok after reading up a bit on Google Guava, you should be able to do something like:

Predicate<OccupancyType> priceFilter = new Predicate<OccupancyType>() {
    public boolean apply(OccupancyType i) {
        return policy.contains(i);
    }
};

and then

return Maps.filterValues(roomPrice, priceFlter);

should do the trick.

Upvotes: 2

Related Questions