Jagat
Jagat

Reputation: 1392

Why does java.util.Map.values() allow you to remove entries from the returned Collection

Why does java.util.Map.values() allow you to delete entries from the returned Collection when it makes no sense to remove a key value pair based on the value? The code which does this would have no idea what key the value(and hence a key) being removed is mapped from. Especially when there are duplicate values, calling remove on that Collection would result in an unexpected key being removed.

Upvotes: 3

Views: 329

Answers (4)

cdeszaq
cdeszaq

Reputation: 31280

The Collection returned is a special Collection, and its semantics are such that it knows how values in it relate back to the Map it came from. The javadoc indicates what Collection operation the returned collection supports.

Upvotes: 0

Kevin
Kevin

Reputation: 56059

I think there is quite often a use for removing a value based on a key; other answers show examples. Given that, if you want to remove a certain value, why would you only want one particular key of it removed? Even if you did, you'd have to know which key you wanted to remove (or not, as the case may be), and then you should just remove it by key anyway.

Upvotes: 0

Mark Peters
Mark Peters

Reputation: 81074

it makes no sense to remove a key value pair based on the value

I don't think you're being imaginative enough. I'll admit there probably isn't wide use for it, but there will be valid cases where it would be useful.

As a sample use case, say you had a Map<Person, TelephoneNumber> called contactList. Now you want to filter your contact list by those that are local.

To accomplish this, you could make a copy of the map, localContacts = new HashMap<>(contactList) and remove all mappings where the TelephoneNumber starts with an area code other than your local area code. This would be a valid time where you want to iterate through the values collection and remove some of the values:

Map<Person, TelephoneNumber> contactList = getContactList();
Map<Person, TelephoneNumber> localContacts = new HashMap<Person, TelephoneNumber>(contactList);

for ( Iterator<TelephoneNumber> valuesIt = localContacts.values().iterator(); valuesIt.hasNext(); ){
    TelephoneNumber number = valuesIt.next();
    if ( !number.getAreaCode().equals(myAreaCode) ) {
        valuesIt.remove();
    }
}

Especially when there are duplicate values, calling remove on that Collection would result in an unexpected key being removed.

What if you wanted to remove all mappings with that value?

Upvotes: 6

Jon Bright
Jon Bright

Reputation: 13738

It has to have a remove method because that's part of Collection. Given that, it has the choice of allowing you to remove values or throwing an UnsupportedOperationException. Since there are legitimate reasons that you might want to remove values, why not choose to allow this operation?

  • Maybe there's a given value where you want to remove every instance of it from the Map.
  • Maybe you want to trim out every third key/value pair for some reason.
  • Maybe you have a map from hotel room number to occupancy count and you want to remove everything from the map where the occupancy count is greater than one in order to find a room for someone to stay in.
  • ...if you think about it more closely, there are plenty more examples like this...

In short: there are plenty of situations where this might be useful and implementing it doesn't harm anyone who doesn't use it, so why not?

Upvotes: 6

Related Questions