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