I have the list of persons and if the list of Input is 3,0,2,7,0,8
I want the output to be 2,3,7,8,0,0
With the following code, i can sort only non zero numbers to get 2,3,7,8
as output.
sortedList = personList.stream()
.filter(Person -> Person.getAge()>0)
.sorted(Comparator.comparingInt(Person::getAge))
.collect(Collectors.toList());
zeroList=personList.stream()
.filter(Person -> Person.getAge()==0)
.collect(Collectors.toList());
sortedList.addAll(zeroList);
Can the above two statements be merged into a single statement?
The split() method of the string class accepts a string representing a delimiter, splits the current string into an array of tokens. Using this method split the given string into an array of tokens. The parseInt() method of the Integer class accepts a String value and converts it into an integer.
Collections class sort() method is used to sort a list in Java. We can sort a list in natural ordering where the list elements must implement Comparable interface. We can also pass a Comparator implementation to define the sorting rules.
You can use radix sort, counting sort, there are lots of O(n) sorts.
You can make sure that zeros go to the end by writing an appropriate comparator:
sortedList = personList.stream()
.sorted((p1, p2) -> {
int a = p1.getAge();
int b = p2.getAge();
if (a == 0 && b == 0) return 0;
if (a == 0) return 1;
if (b == 0) return -1;
return Integer.compare(a, b);
})
.collect(Collectors.toList());
Or slightly more compactly:
sortedList = personList.stream()
.sorted((p1, p2) -> {
int a = p1.getAge();
int b = p2.getAge();
return a == 0 || b == 0 ? Integer.compare(b, a) : Integer.compare(a, b);
})
.collect(Collectors.toList());
A nice simple way to put 0s at the end of the sort is to treat them as large values in the comparator:
Comparator.comparingInt(p -> p.getAge() == 0 ? Integer.MAX_VALUE : p.getAge())
What you want, is a rotation; when you simply sort by age, the elements are in the right order, when you consider the result list to be a ring, so you only want to start the list after the last zero-age value:
┌───────────────────────────┐
└─ 0 0 2 3 7 8 <─┘
2 3 7 8 0 0
sortedList = personList.stream()
.sorted(Comparator.comparingInt(Person::getAge))
.collect(Collectors.toCollection(ArrayList::new));
Collections.rotate(sortedList, -(int)personList.stream().filter(p->p.getAge()==0).count());
Alternatively, you can rotate the age values within the int
value range while comparing. This works, because we can preclude negative ages, so we can rotate the numbers so that zero becomes the MAX_VALUE
while all other numbers keep their relative order.
sortedList = personList.stream()
.sorted(Comparator.comparingInt(p -> p.getAge()-Integer.MIN_VALUE-1))
.collect(Collectors.toList());
By the way, this is equivalent to
sortedList = personList.stream()
.sorted((p1, p2) -> Integer.compareUnsigned(p1.getAge()-1, p2.getAge()-1))
.collect(Collectors.toList());
Understanding the two's complement is needed to understand the solution.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With