Search code examples
javagenericsjava-streamcollectors

Collector.toMap using generics


I am having hard time using streaming API in Java for generics map. I have a map which extends LinkedHashMap in the following way

public class LRUCache<K, V> extends LinkedHashMap<K, V> {
  private int size;

  public LRUCache(int size) {
    super(size);
    this.size = size;
  }

  @Override
  protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
    return size() > size;
  }

  public LRUCache<K, V> collect() {
    return entrySet()
        .stream()
        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)
    );
  }

}

I am experimenting with a dummy method collect which will actually stream on the entrySet, apply some filters on it and then return a new LRUCache, but Collectors.toMap keep throwing an error which says

"Non-static method cannot be referenced from a static context"

I know this is some issue with Collectors.toMap generics definition. But, I am not able to figure out the right generics to get rid of the error and achieve the streaming and collecting functionality


Solution

  • LinkedHashMap includes in its implementation is a no-argument constructor that acts as a supplier to the toMap collect operation. You can introduce the same as well by including:

    public LRUCache() {
        this(10); // default size
    }
    

    Thereafter you can collect the LRUCache implementation using the toMap override with LRUCache::new supplier in the following manner:

    public LRUCache<K, V> collect() {
        return entrySet().stream()
                .collect(Collectors.toMap(Map.Entry::getKey,
                        Map.Entry::getValue, 
                        (a, b) -> a, LRUCache::new));
    }
    

    Note:- That what matters is providing a supplier to collect to a different implementation than a HashMap which is what you get using the other overloaded implementation of toMap.