简体   繁体   中英

Sorting Elements in Place in Java

I am trying to sort a list of given elements by decreasing frequency. If two elements have the same frequency, they should appear in increasing order. For example, given the input: [6, 1000, 3, 3, 1000, 6, 6, 6] the output should be: [6, 6, 6, 6, 3, 3, 1000, 1000] . The elements also must be sorted in place rather than returning a new list.

So far, I have created a HashMap of the key and values, where the key is the element and the value is the frequency. But I'm not quite sure what to do next:

public static void method(List<Integer> items)
{
        int size = items.size();
        int count = 0;
        HashMap<Integer, Integer> map = new HashMap<>();
        for (int i = 0; i < size; ++i)
        {
            int item = items.get(i);
            if (map.containsKey(item))
            {
                map.put(item, map.get(item) + 1);
            }
            else
            {
                map.put(item, 1);
            }
        }
        List list = new LinkedList(map.entrySet());
        Collections.sort(list, new Comparator()
        {
            public int compare(Object o1, Object o2)
            {
                return ((Comparable) ((Map.Entry) (o1)).getValue())
                .compareTo(((Map.Entry) (o2)).getValue());
            }
        });
        HashMap sortedMap = new LinkedHashMap();
        for (Iterator it = list.iterator(); it.hasNext();)
        {
            Map.Entry entry = (Map.Entry) it.next();
            sortedMap.put(entry.getKey(), entry.getValue());
        }
}

You can sort inline as follows :

public static void sortInline(List<Integer> list) {
    Map<Integer, Long> map = list.stream()
            .collect(Collectors.groupingBy(Function.identity(),
                    Collectors.counting())); // frequency map
    Comparator<Integer> frequencyComparison = Comparator
            .<Integer>comparingLong(map::get).reversed(); // sort the entries by value in reverse order 
    list.sort(frequencyComparison.thenComparing(Comparator.naturalOrder())); // then by key for the collisions
}
public static void method(List<Integer> list) {
    Map<Integer, Long> map = list.stream()
                                 .collect(Collectors.groupingBy(Function.identity(), 
                                                                Collectors.counting()));
    list.sort(new Comparator<Integer>() {
         @Override
         public int compare(Integer o1, Integer o2) {
             Long cnt1 = map.get(o1);
             Long cnt2 = map.get(o2);
             int compare = cnt2.compareTo(cnt1);
             if (compare == 0) {
                 return o1.compareTo(o2);
             }
             return compare;
         }
    });
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM