class MapFunctions {

    public static <T, R> LinkedHashMap<R, Integer> getSortedGroupingCounts(List<T> list, Function<T, R> groupFn) {

        if (list == null || list.isEmpty()) {
            return new LinkedHashMap<>(0);
        }

        Map<R, List<T>> grouped = list.stream().collect(groupingBy(groupFn));
        Map<R, Integer> numberOfOccurrancesByGrouping =
                simpleToMap(new ArrayList<>(grouped.entrySet()), Entry::getKey, entry -> entry.getValue().size());

        List<Entry<R, Integer>> entries = new ArrayList<>(numberOfOccurrancesByGrouping.entrySet());
        entries.sort((entry1, entry2) -> entry2.getValue().compareTo(entry1.getValue()));
        LinkedHashMap<R, Integer> sortedMap = new LinkedHashMap<>();
        entries.forEach(entry -> sortedMap.put(entry.getKey(), entry.getValue()));
        return sortedMap;
    }

    private  MapFunctions();

}