2

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());
    }
}
2
  • 1
    What's the problem with the code exactly? Commented Jan 5, 2023 at 12:11
  • 1
    I does not sort, but after some debugging I have replaced the line: return (int)(a.getX() - b.getX()); by: return (int)Math.signum(a.getX() - b.getX()); and now it does. Commented Jan 5, 2023 at 13:00

1 Answer 1

8

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));
Sign up to request clarification or add additional context in comments.

2 Comments

Also, note that Collections.sort(oList, comparator) invokes oList.sort(comparator); so you may as well just invoke it directly.
@AndyTurner I was sticking with the OP's style, but you're right, might as well note that too. Edited.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.