// onjava/TypeCounter.java // (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. // Visit http://OnJava8.com for more book information. // Counts instances of a type family package onjava; import java.util.*; import java.util.stream.*; public class TypeCounter extends HashMap, Integer> { private Class baseType; public TypeCounter(Class baseType) { this.baseType = baseType; } public void count(Object obj) { Class type = obj.getClass(); if(!baseType.isAssignableFrom(type)) throw new RuntimeException( obj + " incorrect type: " + type + ", should be type or subtype of " + baseType); countClass(type); } private void countClass(Class type) { Integer quantity = get(type); put(type, quantity == null ? 1 : quantity + 1); Class superClass = type.getSuperclass(); if(superClass != null && baseType.isAssignableFrom(superClass)) { countClass(superClass); } } @Override public String toString() { String result = entrySet().stream() .map(pair -> String.format("%s=%s", pair.getKey().getSimpleName(), pair.getValue())) .collect(Collectors.joining(", ")); return "{" + result + "}"; } }