Search code examples
javasortingdictionaryguavamultimap

How to sort object using a multi map?


Hi I'm trying to sort an object based on a value of that object. Originally I used TreeMap which did the sorting but there were some non-unique keys which were removed so that didn't work. I googled around and came across Guava MultiMap. But how do I actually use this to sort the values?

Basically I'm trying to sort budget information based on the diffYTD_percentage value. Thanks!

Multimap<Double, BudgetInformation> multiMap = ArrayListMultimap.create();
    for (Budget budget : budgets) {
        BudgetInformation budgetInfo = getBudget(budget.getId());
        double actualToDate = budgetInfo.getActualToDate();
        double budgetToDate = budgetInfo.getTotalBudgetToDate();
        double diffYTD_value = budgetToDate - actualToDate;
        double diffYTD_percentage_value = 0.0;
        if (budgetToDate != 0.0) {
            double fraction = actualToDate / budgetToDate;
            fraction = fraction - 1;
            diffYTD_percentage_value = fraction * 100;
        }
        multiMap.put(diffYTD_percentage_value, budgetInfo);
    }

    Iterator<BudgetInformation> budgetIterator = multiMap.values().iterator();

Solution

  • Using Tree in order to sort collection is wrong approach. In Java there are dedicated utility methods to sort list, Collections.sort(List<T extends Comparable<? super T>> list) and Collections.sort(List<T> list, Comparator<? super T> c). The first is used to sort list where elements have natural ordering (basically implement Comparable interface), the later is used in cases like your own, when you need to sort elements using custom ordering.

    So, basically what you need to do is to create Comparator that will compare two BusinessInfo instances based on diffYTD_percentage_value and call Collections.sort with this comparator.

        Comparator<BudgetInformation> budgetInfoCmp = new Comparator<BudgetInformation>() {
            private double getDiffYTDPercentage(BudgetInformation budgetInfo) {
                double actualToDate = budgetInfo.getActualToDate();
                double budgetToDate = budgetInfo.getTotalBudgetToDate();
                double diffYTDValue = budgetToDate - actualToDate;
                double diffYTDPercentageValue = 0.0;
                if (budgetToDate != 0.0) {
                    double fraction = actualToDate / budgetToDate;
                    fraction = fraction - 1;
                    diffYTDPercentageValue = fraction * 100;
                }
                return diffYTDPercentageValue;
            }
    
            @Override
            public int compare(BudgetInformation o1, BudgetInformation o2) {
                return Double.compare(getDiffYTDPercentage(o1), getDiffYTDPercentage(o2));
            }
        };
    
        List<BudgetInformation> budgetInformationsToSort = getBudgetInformations();
        Collections.sort(budgetInformationsToSort, budgetInfoCmp);
    

    Also try to avoid using underscore in variable naming, as under Java naming convention variable names should be in camel case.