In the code below the object someObj
has two properties, a float x
and an int pnt
.
An ArrayList<someObj>
is created and is then sorted using a Comparator
interface according to x. The property pnt
is intended to keep track of the elements after the sorting.
I've copied the code from https://www.geeksforgeeks.org/collections-sort-java-examples/ and modified it a little to suit my needs. I wonder what might be wrong, it just does not do its sorting job.
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Random;
public class ArrayListSorting {
public static void main(String[] args) {
// 20 random numbers will be used for the test
final int sz=20;
Random rand = new Random();
ArrayList<someObj> oList=new ArrayList<someObj>();
// Build the list
for(int i=0;i<sz;i ) {
oList.add(new someObj(i,rand.nextFloat()));
}
// Print the list before sorting
for(int i=0;i<sz;i ) {
System.out.println(i "\t" oList.get(i).getX());
}
Collections.sort(oList, new sorter());
// ...and after sorting
for(int i=0;i<sz;i ) {
int j=oList.get(i).getPnt();
System.out.println(j "\t" oList.get(i).getX());
}
}
}
class someObj {
private float x;
private int pnt;
public someObj(int pnt,float x) {
this.pnt=pnt;
this.x=x;
}
public int getPnt() {
return pnt;
}
public float getX() {
return x;
}
}
class sorter implements Comparator<someObj> {
public int compare(someObj a, someObj b) {
return (int)(a.getX() - b.getX());
}
}
CodePudding user response:
nextFloat()
will generate a float
in the range [0,1), and by subtracting any two such values in the comparator, you'll get a value in the range (-1, 1). When you cast this to an int
you'll get a 0, meaning that according to this comparator they are all equivalent, and the list will retain its order.
You can solve this by not implementing the comparator with -
, but by reusing Float
's compare
method:
class sorter implements Comparator<someObj> {
public int compare(someObj a, someObj b) {
return Float.compare(a.getX(), b.getX());
}
}
Or better yet, use Comparator.comparing
to create this comparator on the fly:
Collections.sort(oList, Comparator.comparing(someObj::getX));
EDIT:
As Andy Turner noted in the comments, Collections.sort
is a bit outdated. Since JDK 8, lists have their own sort
method you can invoke directly:
oList.sort(Comparator.comparing(someObj::getX));