Sarah
Sarah

Reputation: 43

Why isn't the sort method working?

I have to sort an array of fractions here is my code for the class which is working fine.

public class Fraction implements Comparable<Fraction>{
    private int numerator;
    private int denominator;

    public Fraction(int num, int den){
        numerator = num;
        denominator = den;
    }

    public int compareTo(Fraction fraction){
        if(decimalValue()>fraction.decimalValue()){
            return 1;
        }else if(decimalValue()<fraction.decimalValue()){
            return -1;
        }else{
            return 0;
        }
    }
    public Fraction reduce(int numerator, int denominator){

  if(numerator==0&&denominator==0){
     numerator = 0;
     denominator = 0;
  }
  else{
     for(int x = Math.min(Math.abs(numerator), Math.abs(denominator)); x>0; x--){
        if(denominator == numerator){
           numerator = 1;
           denominator = 1;
        }
        else if(numerator == 0){
           numerator = 0;
           denominator = 1;
        }
        else if(numerator%x==0 && denominator%x==0){
           numerator = numerator/x;
           denominator = denominator/x; 
        }
     }
  }

    public double decimalValue(){
        double decimal = (numerator*1.0)/(1.0*denominator);
        return decimal;
    } 
    public String toString(){
        reduce(numerator, denominator);
        return ((numerator) + "/" + (denominator));
    }
}

For some reason the sort() is not working if I used it with a comparator like in the answer it works but I don't understand why this doesn't work. Here is the tester:

public class FractionChecker{
    public static void main (String[]args){
        int n, d;
        Random rand = new Random();
        Fraction[] f = new Fraction [20];
        for (int j= 0; j<20; j++){
            n = rand.nextInt(20);
            d = rand.nextInt(19)+1;           
            f[j] = new Fraction (n,d);
        }

        System.out.println("Unsorted " + Arrays.toString(f));
        Arrays.sort(f);
    }
}

Error:

      ----jGRASP exec: java FractionChecker
      Unsorted [7/6, 15/14, 5/15, 8/9, 19/16, 16/5, 11/16, 2/9, 11/10, 10/12,       12/11, 9/18, 15/4, 11/4, 10/7, 12/8, 13/14, 19/5, 19/15, 13/5]
       Exception in thread "main" java.lang.ClassCastException: Fraction cannot be cast to java.lang.Comparable
      at java.util.Arrays.mergeSort(Arrays.java:1144)
      at java.util.Arrays.mergeSort(Arrays.java:1155)
      at java.util.Arrays.mergeSort(Arrays.java:1155)
      at java.util.Arrays.sort(Arrays.java:1079)
      at FractionChecker.main(FractionChecker.java:18)

     ----jGRASP wedge: exit code for process is 1.
     ----jGRASP: operation complete.

This is the error I am getting when I use Arrays.sort(f) and I am not sure why.

Upvotes: 0

Views: 745

Answers (3)

rudolfovic
rudolfovic

Reputation: 3276

The code below works and prints success

import java.util.Arrays;

public class Fraction implements Comparable<Fraction>{
    private int numerator;
    private int denominator;

    public Fraction(int num, int den){
        numerator = num;
        denominator = den;
    }

    public int compareTo(Fraction fraction){
        if(decimalValue()>fraction.decimalValue()){
            return 1;
        }else if(decimalValue()<fraction.decimalValue()){
            return -1;
        }else{
            return 0;
        }
    }

    public double decimalValue(){
        double decimal = (numerator*1.0)/(1.0*denominator);
        return decimal;
    } 
    public String toString(){
        return ((numerator) + "/" + (denominator));
    }

    public static void main(String[] a) {
        Fraction[] fractions = new Fraction[2];
        fractions[0] = new Fraction(1,1);
        fractions[1] = new Fraction(2,3);
        Arrays.sort(fractions);
        System.out.println("success");
    }
}

Upvotes: 0

TNT
TNT

Reputation: 2920

Collections.sort expects a List whose type implements Comparable. You're providing an array of Fraction objects instead.

You should use Arrays.sort instead:

Arrays.sort(f);

If the above throws a ClassCastException for some reason, you can try this version of Arrays.sort, which requires a Comparator as an argument that will do the comparing:

Arrays.sort(f, new java.util.Comparator<Fraction>() {
    @Override
    public int compare(Fraction f1, Fraction f2) {
        return f1.compareTo(f2);
    }
});

Upvotes: 1

rudolfovic
rudolfovic

Reputation: 3276

I don't see your decimalValue code. A better way to compare fractions in any case may be:

long left = numerator * other.denominator;
long right = other.numerator * denominator;

if (left == right) {
  return 0;
} else if (left < right) {
  return -1;
} else /* if (left > right) */ {
  return 1;
}

Not that this will increase your performance drastically but it is just neater and handles division by zero in a sensible way.

Upvotes: 0

Related Questions