protected List<I> rankItems(final Map<I, Double> userItems) {
        List<I> sortedItems = new ArrayList<>();
        if (userItems == null) {
            return sortedItems;
        }
        Map<Double, Set<I>> itemsByRank = new HashMap<>();
        for (Map.Entry<I, Double> e : userItems.entrySet()) {
            I item = e.getKey();
            double pref = e.getValue();
            if (Double.isNaN(pref)) {
                // we ignore any preference assigned as NaN
                continue;
            }
            Set<I> items = itemsByRank.get(pref);
            if (items == null) {
                items = new HashSet<>();
                itemsByRank.put(pref, items);
            }
            items.add(item);
        }
        List<Double> sortedScores = new ArrayList<>(itemsByRank.keySet());
        Collections.sort(sortedScores, Collections.reverseOrder());
        for (double pref : sortedScores) {
            List<I> sortedPrefItems = new ArrayList<>(itemsByRank.get(pref));
            // deterministic output when ties in preferences: sort by item id
            Collections.sort(sortedPrefItems, Collections.reverseOrder());
            for (I itemID : sortedPrefItems) {
                sortedItems.add(itemID);
            }
        }
        return sortedItems;
    }
protected List < I > rankItems ( final Map < I , Double > userItems ) { List < I > sortedItems = new ArrayList < > ( ) ; if ( userItems == null ) { return sortedItems ; } Map < Double , Set < I > > itemsByRank = new HashMap < > ( ) ; for ( Map . Entry < I , Double > e : userItems . entrySet ( ) ) { I item = e . getKey ( ) ; double pref = e . getValue ( ) ; if ( Double . isNaN ( pref ) ) { continue ; } Set < I > items = itemsByRank . get ( pref ) ; if ( items == null ) { items = new HashSet < > ( ) ; itemsByRank . put ( pref , items ) ; } items . add ( item ) ; } List < Double > sortedScores = new ArrayList < > ( itemsByRank . keySet ( ) ) ; Collections . sort ( sortedScores , Collections . reverseOrder ( ) ) ; for ( double pref : sortedScores ) { List < I > sortedPrefItems = new ArrayList < > ( itemsByRank . get ( pref ) ) ; Collections . sort ( sortedPrefItems , Collections . reverseOrder ( ) ) ; for ( I itemID : sortedPrefItems ) { sortedItems . add ( itemID ) ; } } return sortedItems ; }
Ranks the set of items by associated score.

@param userItems map with scores for each item
@return the ranked list