Home > Enterprise >  How to assign Map<String, T> in class using a generic function without casting
How to assign Map<String, T> in class using a generic function without casting

Time:08-12

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()));
}
  • Related