Reputation: 201
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
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
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