I am working on some code. I have a class like this.
class Document {
//assume there are getters and setters
Map<String, Number> idToRatings;
Map<String, String> idToNames;
public <T> void setNewMapAttribute(Function<Map<String, T>, Map<String, T>> mapConsumer){
this.setIdToRatings((Map<String, Number>) mapConsumer.apply((Map<String, T>) this.idToRatings()));
this.idToNames((Map<String, String>) mapConsumer.apply((Map<String, T>) this.idToNames()));
}
}
Then in an another class I have a function like this.
private <T> Map<String, T> filterMapKeys(Map<String, T> givenMap) {
return givenMap
.entrySet()
.stream()
.filter(stringTEntry -> attributeIds.contains(stringTEntry.getKey()))
.collect(Collectors.toMap(Entry::getKey, Entry::getValue));
}
This method would then be used like this ideally
doucment.setNewMapAttribute(this::filterMapKeys);
I would like to create a way where I can filter any of properties in the class by a list of ids. Since the Maps in Document
contain different key values, I need to use generics. The code in the end would take in a list of ids like List.of("123", "456")
and return a Document that only has the ids 123 and 456 in either of it's properties. However, intellij is requiring the casting in setNewMapAttribute
which I would like to avoid.
Is there anything I can do about this casting? Is there a different type of generic signature I can use to make the function work without the casting?
It makes sense to me that if my function only uses the key type of the Map, then I should be able to filter on ids within all attributes without the casting seen in setNewMapAttribute
. The type of the value in Maps, does not concern my filtering function.
CodePudding user response:
If I properly understood requirements...
@FunctionalInterface
interface MapFilter {
<T> Map<String, T> filter(Map<String, T> map);
}
public void setNewMapAttribute(MapFilter mapConsumer) {
this.setIdToRatings(mapConsumer.filter(this.getIdToRatings()));
this.setIdToNames(mapConsumer.filter(this.getIdToNames()));
}