Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java generics incompatible types (no instance(s) of type variable(s) exist)

The question title may seem to be same as some other post but the content is different. So please don't mark it duplicate.

Problem:

I have the below class:

public class SCDTO extends RDTO {
    private List<String> sCPairs = Collections.emptyList();

    public SCDTO(List<String> sCPairs) {
        this.sCPairs = sCPairs;
    }

    //Getter setter
    
}

I am trying to using the below lambda expression to set the sCPairs.

sCPairsObject.setSCPairs(
         util.getSCMap().entrySet().stream()
        .filter(entry -> entry.getValue().contains("abc"))
        .collect(Collectors.toCollection(ArrayList<String>::new))
);

But I have an compilation error saying:

no instance(s) of type variable(s) exist so that Entry<String, List<String>> conforms to String

util.getSCMap returns Map<String, List<String>>.

Can anyone please explain why this is happening and how to solve it?

Thanks.

like image 868
Sumit Avatar asked Jan 01 '23 20:01

Sumit


2 Answers

You are streaming entries from the map:

sCPairsObject.setSCPairs(util.getSCMap().entrySet().stream()

Then filtering out some of them:

.filter(entry -> entry.getValue().contains("abc"))

now you need to map the entries to List, for example:

.map(entry -> entry.getValue())

and stream the contents of all these lists as one stream:

.flatMap(List::stream)

Finally collect the values into a list:

.collect(Collectors.toList());
like image 82
Adriaan Koster Avatar answered Jan 08 '23 00:01

Adriaan Koster


Your stream pipeline finds all the Map entries whose value List<String> contains the String "abc", and tries to collect them into a List<String>.

You didn't specify how you intend to convert each Map.Entry<String,List<String>> element that passes the filter into a String. Depending on the required logic, perhaps you are missing a map() step after the filter.

For example, if you wish to collect all the keys having a value that passes the filter into a List<String>:

 sCPairsObject.setSCPairs(util.getSCMap()
                              .entrySet()
                              .stream()
                              .filter(entry -> entry.getValue().contains("abc"))
                              .map(Map.Entry::getKey)
                              .collect(Collectors.toCollection(ArrayList<String>::new)));
like image 28
Eran Avatar answered Jan 08 '23 01:01

Eran