code: 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;
      }
docs: Ranks the set of items by associated score.
  
  @param userItems map with scores for each item
  @return the ranked list