Jakub
Jakub

Reputation: 201

Sorting Integer List. The same elements at beginning

I have random list of 5 elements like [14, 9, 7, 7, 14] or [2, 7, 11, 7, 8] and I would like to sort them. First I call:

Collections.sort(List);

And it gives me lists like this: [7, 7, 9, 14, 14] and [2, 7, 7, 8, 11]. I would like to achieve situation when the same elements of the list are in first places in my list. Like:

[7, 7, 9, 14, 14] after sort: [7, 7, 14, 14, 9]

[2, 7, 7, 8, 11] after sort: [7, 7, , 8, 11]

[4, 8, 8, 8, 9] after sort: [8, 8, 8, 4, 9]

[5, 8, 8, 8, 8] after sort: [8, 8, 8, 8, 5]

How Can I achieve that? Is there any good way to do this?

Upvotes: 0

Views: 97

Answers (2)

ThrowAway101
ThrowAway101

Reputation: 21

following ajb advice, here is the Java 8 code using as he said fancy comparators,

  public static int[] funSort(int[] array) {
    HashMap<Integer, Integer> map = new HashMap<>();
    for(int value: array) {
      map.merge(value, 1, Integer::sum);
    }
    return map.entrySet().stream()
      .sorted(Map.Entry.<Integer, Integer>comparingByValue()
          .thenComparing(Map.Entry.comparingByKey())
          .reversed())
      .flatMap(e -> Collections.nCopies(e.getValue(), e.getKey()).stream())
      .mapToInt(Integer::intValue)
      .toArray();
  }

Upvotes: 1

sidgate
sidgate

Reputation: 15244

  public class Sort {

  public static void main(String[] args) {
    int[] arr = new int[]{14, 9, 7, 7, 14};
    Map<Integer, Temp> map = new HashMap<>();

    for(int i: arr){
      Temp t = map.getOrDefault(i, new Temp(i));
      map.put(i,t.increment()); 
    }
    List<Temp> l = new ArrayList<>(map.values());
    Collections.sort(l, (o,t)-> o.count ==t.count ?o.value - t.value : t.count-o.count);

    List<Integer> finalList = new ArrayList<>() ;
    for(Temp t: l){
       for(int i=0;i<t.count;i++){
         finalList.add(t.value);
       }
    }
    System.out.println(finalList);
  }

  static class Temp{
    int value, count;
    public Temp(int i) {
      value=i;
    }
    public Temp increment(){
      count++;
      return this;
    }

  }

Trying out the Java-8 way

public class Sort {

  public static void main(String[] args) {
    int[] arr = new int[] { 14, 9, 7, 7, 14 };
    Map<Integer, Temp> map = new HashMap<>();

    for (int i : arr) {
      Temp t = map.getOrDefault(i, new Temp(i));
      map.put(i, t.increment());
    }

    List<Integer> collect = map.values().stream()
      .sorted((o, t) -> o.count == t.count ? o.value - t.value : t.count - o.count)
      .map(t -> IntStream.range(0, t.count).map(i -> t.value)
      .collect(ArrayList<Integer>::new, ArrayList::add, ArrayList::addAll))
      .flatMap(ll -> ll.stream())
      .collect(Collectors.toList());
    System.out.println(collect);

  }

  static class Temp {
    int value, count;
    public Temp(int i) {
      value = i;
    }
    public Temp increment() {
      count++;
      return this;
    }
  }
}

Upvotes: 3

Related Questions