How to override compareTo Double method? - java

I tried to override compareTo method however I see compiler uses Java.lang.Double.compareTo method instead of my compareTo.
What is wrong here and what should I fix and change so my own compareTo method will be used?
package GenerecEx;
import java.util.ArrayList;
import java.util.Collections;
public class ArraySort implements Comparable{
double val;
static ArrayList<Double> a=new ArrayList<Double>();
public static void main(String[] args) {
a.add(2.4);
a.add(8.4);
a.add(9.4);
a.add(4.4);
a.add(6.4);
sort(a);
printList(a);
}
public static void printList(ArrayList a1)
{
System.out.println(a1.toString());
}
static public void sort(ArrayList <Double> a1)
{
for (int i=0;i<a1.size();i++){
for(int j=0;j<a1.size()-i-1;j++){
if (a1.get(j).compareTo(a1.get(j+1))>0){
double temp = a1.get(j);
a1.set(j,a1.get(j+1) );
a1.set(j+1, temp);
}
}
}
}
#Override
public int compareTo(Object element)
{
if (this.val < (Double) element)
return -1;
else return 1;
}
}

Implementing the Comparable interface allows you to override the compareTo method on the implementing class. Having implemented Comparable on the ArraySort class, your compareTo method should actually be comparing objects of type ArraySort, not generic Objects cast as Double.

Related

How to bypass Java not being able to extend from multiple classes

I think I have a design problem in my Java app, but I cannot figure out how to solve or bypass it.
Say I have an interface and an abstract class implementing it as follows:
public interface IntegerCollection extends Collection<Integer> {
public int sum();
}
public abstract class AbstractIntegerCollection
extends AbstractCollection<Integer> implements IntegerCollection {
public int sum() {
// fancy code to calculate the sum of all collection members (just an example)
}
}
Now I would want to make this class instantiable by using the existing implementations of Collection (e.g., LinkedList); something like this:
public class IntegerLinkedList extends AbstractIntegerCollection, LinkedList<Integer> {
}
IntegerCollection ic = new IntegerLinkedList();
However, this does not work because Java does not support extending several classes. Also it looks quite ugly to me, as there is a mixture of hierarchies.
Of course, I could let IntegerLinkedList implement IntegerCollection instead of letting it extend AbstractIntegerCollection. But then, I would have to repeat the code for sum() in all other implementations (e.g., IntegerArrayList).
Is there a better way to do this?
I'm not sure what exactly, you are trying to achieve, but rather you could implements List instead of extending LinkedList
public class IntegerLinkedList
extends AbstractIntegerCollection
implements List<Integer>
{
}
But, you need to implements all abstract method of List.
Since java 8 it has been possible to include implementations in an interface by using the default keyword. Therefore you don't need AbstractIntegerCollection - all the common code can be put in the interface. Here is an example:
import java.util.Collection;
import java.util.LinkedList;
public class Main {
interface IntegerCollection extends Collection<Integer> {
default int sum() {
int sum = 0;
for (int a : this)
sum += a;
return sum;
}
}
static class IntegerLinkedList extends LinkedList<Integer> implements IntegerCollection {
}
public static void main(String[] args) {
IntegerCollection list = new IntegerLinkedList();
list.add(1);
list.add(2);
list.add(3);
System.out.println(list.sum()); // Prints 6
}
}
This works, but I'm not sure it's a good idea. I'd think very carefully before extending a class like LinkedList. Some people also consider it an anti-pattern to extend generic classes with non-generic ones.
Another thing to be aware of is that it is not possible to write default methods for the methods of Object like equals and toString etc.
Since you are using Java 7, the above solution is not available. However, with a load of tedious forwarding methods, you can do it using composition rather than inheritance. Josh Bloch's book Effective Java gives a very good explanation of why composition is preferable anyway. Here is an (incomplete) example - you'll need to add a few more forwarding methods to avoid UnsupportedOperationExceptions when you try doing other things with the list.
import java.util.*;
public class Main {
abstract static class AbstractIntegerCollection extends AbstractCollection<Integer> {
public int sum() {
int sum = 0;
for (int a : this)
sum += a;
return sum;
}
}
static class IntegerLinkedList extends AbstractIntegerCollection implements List<Integer> {
private final List<Integer> list = new LinkedList<>();
#Override
public Iterator<Integer> iterator() {
return list.iterator();
}
#Override
public int size() {
return list.size();
}
#Override
public boolean addAll(int index, Collection<? extends Integer> c) {
return list.addAll(index, c);
}
#Override
public Integer get(int index) {
return list.get(index);
}
#Override
public Integer set(int index, Integer element) {
return list.set(index, element);
}
#Override
public boolean add(Integer element) {
return list.add(element);
}
#Override
public void add(int index, Integer element) {
list.add(index, element);
}
#Override
public Integer remove(int index) {
return list.remove(index);
}
#Override
public int indexOf(Object o) {
return list.indexOf(o);
}
#Override
public int lastIndexOf(Object o) {
return list.lastIndexOf(o);
}
#Override
public ListIterator<Integer> listIterator() {
return list.listIterator();
}
#Override
public ListIterator<Integer> listIterator(int index) {
return list.listIterator(index);
}
#Override
public List<Integer> subList(int fromIndex, int toIndex) {
return list.subList(fromIndex, toIndex);
}
// More of these
}
public static void main(String[] args) {
IntegerLinkedList list = new IntegerLinkedList();
list.add(1);
list.add(2);
list.add(3);
System.out.println(list.sum()); // Prints 6
}
}
This solution is far from perfect. For one thing, it would be better if IntegerLinkedList extended AbstractList<Integer> rather than just AbstractCollection<Integer>, but then you couldn't extend AbstractIntegerCollection too.

Java OOP: referencing subclass object

I have an ArrayClass and mergeSortArray extends it. And mergeSortArray contains a mergeSort() method. However, since I used super to call a constructor from the superclass, I do not know how to refer to the mergeSortArray (the subclass object / array) and pass it as a parameter in the mergeSort method. In fact, is this even feasible ? I know I can do this in a NON- OOP way. However, I am keen to know how to do this in an OOP way.
Please correct me if I have said incorrect, as I am new to Java and I want to learn more about it.
// ArrayClass Object
import java.util.*;
import java.io.*;
import java.math.*;
public class ArrayClass{
public int[] input_array;
public int nElems;
public ArrayClass(int max){
input_array = new int [max];
nElems = 0;
}
public void insert(int value){
input_array[nElems++] = value;
}
public void display(){
for(int j = 0; j < nElems; j++){
System.out.print(input_array[j] + " ");
}
System.out.println("");
}
}
import java.io.*;
import java.util.*;
import java.math.*;
class mergeSortArray extends ArrayClass{
public mergeSortArray(int max){
super(max);
}
public void methodOne(){
int[] output_array = new int[super.nElems];
mergeSort( // ************* // ,output_array,0, super.nElems -1);
}
................
}
I am not sure what I should put to replace ****** such that I can pass mergeSortArray as a parameter into the mergeSort method.
There isn't a mergeSortArray. You inherit input_array like (and no need for super.nElems you inherit that too),
mergeSort( input_array, output_array, 0, nElems - 1);
Your sub-class will inherit everything that is protected or greater visibility (not private), however your ArrayClass gives you both public fields
public int[] input_array;
public int nElems;
They should probably be protected and have accessor methods (getters).
protected int[] input_array;
protected int nElems;
public int size() {
return nElems;
}
public int[] getInputArray() {
return input_array;
}
First of all, I suggest you not to have public fields on OO code. You got two public fields (input_array and nElems), you should change them to private and create acessors if you need.
Then, to refer to those fields on the subclass, you can either use a protected acessor if you wish to hide the acessor from the rest of the API or a public one, if it's part of your public API. That way, on your ArrayClass:
public class ArrayClass {
private int[] input_array;
private int nElems;
//this may be public
protected int[] getInputArray() {
return input_array;
}
and when you get to call your mergeSort method, you can use getInputArray()

Using compareTo in Java to Sort

Basically i'm attempting to write a compareTo that does the comparison based on the value of compareByWord. If compareByWord is true, I want it to compare based on the word, but if it's false, I want it to compare based on count.
class WordCount implements Comparable //Error saying WordCount must implement the inherited abstract method Comparable.compareto (Object)
{
String word;
int count;
static boolean compareByWord;
public WordCount(String aWord)
{
setWord(aWord);
count = 1;
}
private void setWord(String theWord)
{
word=theWord;
}
public void increment()
{
count+=1;
}
public static void sortByWord()
{
compareByWord = true;
}
public static void sortByCount()
{
compareByWord = false;
}
public String toString()
{
String result = String.format("%s (%d)",word, count);
return result;
}
public String getWord()
{
return word;
}
public int getCount()
{
return count;
}
#Override
public int compareTo(WordCount other) { //Error saying compareTo (WordCount) of type WordCount must override or implement a supertype method.
if (compareByWord == true)
{
return word.compareTo(other.getWord());
}
if (compareByWord == false)
{
return count.compareTo(other.getCount()); //Error saying it cannot invoke compareTo int on primitive type int.
}
return 0;
}
}
My class was perfect before I tried to implement this, not sure where I'm going wrong here. Any and all help is much appreciated.
Change the declaration to
class WordCount implements Comparable<WordCount> { // generic version
The method signature in Comparable<WordCount> is compareTo(WordCount obj) while for the raw version it's compareTo(Object obj).
With the usage of #Override, the compiler makes sure that you actually override the parent method. And the problem is that compareTo(WordCount obj) does not override compareTo(Object obj).
must implement the inherited abstract method Comparable.compareto (Object)
So pass Object, not WordCount. Now you're trying to overload this function, not override.
Use Integer count not int count. Integer is an object which implements Comparable whereas int is a primitive as the error message describes. For javadocs:
public final class Integer
extends Number
implements Comparable<Integer>
Make sure you change your accessor methods to use Integer as well of course.
That will take care of your final error.

Java Generic Misbound

import java.util.ArrayList;
import java.util.Iterator;
import java.util.Collections;
public interface Comparable<T> {
int compareTo(T other);
}
public class Joueur implements Comparable<Joueur> {
private int points;
private int idJoueur;
public Joueur(int aIdJoueur, int aPoints)
{
points= aPoints;
idJoueur = aIdJoueur;
}
public Joueur(int aIdJoueur, int aPoints)
{
points= aPoints;
idJoueur = aIdJoueur;
}
public int getIdJoueur()
{
return idJoueur;
}
public int compareTo(Joueur autre) {
// TODO Auto-generated method stub
if (points < autre.points) return -1;
if (points > autre.points) return 1;
return 0;
}
public class CollectionJoueur {
ArrayList<Joueur> j = new ArrayList<Joueur>();
public CollectionJoueur(int aIdJoueur, int aPoints)
{
Joueur ajouterJ = new Joueur(aIdJoueur, aPoints);
ajouter(ajouterJ);
}
public void ajouter(Joueur joueur)
{
j.add(joueur);
}
public iterateurJoueur creerIterateur()
{
Collections.sort(j);
Iterator<Joueur> itrJoueur = j.iterator();
while(itrJoueur.hasNext())
{
}
}
}
So here's my problem, I have been trying to do comparable sort, but in the collections sort it gave me an error of generic misbound. I have a class collection to put the player into the arraylist then i have to sort them out in ascending order.
You should implement java.lang.Comparable interface, not your own Comparable interface.
http://docs.oracle.com/javase/7/docs/api/java/lang/Comparable.html
You'll notice that Collections.sort(..) is defined as
public static <T extends Comparable<? super T>> void sort(List<T> list) {
In other words, it expects a type that is a sub type of java.lang.Comparable. Your class is not a sub type of java.lang.Comparable. What you are trying to do with Collections.sort(..) is not possible.
Get rid of your Comparable type and use java.lang.Comparable.
Or write your own sorting method.

Java priority queues and comparable interface

I've just been learning about priority queues and thought I'd try how it behaves with comparable interface.
Code Snippet:
import java.util.PriorityQueue;
class kinga implements Comparable<Double> {
double time=909.909;
double d;
public kinga(double a) {
this.d=a;
}
public int compareTo(Double d) {
return Double.compare(d, time);
}
public static void main(String arg[]) {
PriorityQueue<kinga> r=new PriorityQueue<kinga>();
r.add( new kinga(4545.45));
r.add( new kinga(45.4));
r.add( new kinga(1235.45));
System.out.println(r.poll()+" "+r.poll()+" "+r.poll());
}
}
It compiles but gives me Exception in thread "main" java.lang.ClassCastException: kinga cannot be cast to java.lang.Double.
What is wrong here. Can somebody tell me how comparable and priority queues work?
kinga should be comparable with kinga, not Double, so:
class kinga implements Comparable<kinga>
which means your compareTo method has to be changed to this:
public int compareTo(kinga o) {
return Double.compare(o.d, d);
}
class kinga implements Comparable<Double>
That doesn't make sense. Although your class will compare fine with Double, Double is unaware of that, and won't compare fine with instances of kinga, which will break the Comparable contract. And since a kinga can't compare with another kinga, you can't use a PriorityQueue<kinga>.
It should be
class Kinga implements Comparable<Kinga>
(note the upper-case, to respect the Java naming conventions), which means: Kinga instances are comparable together.
The compareTo method should be
#Override
public int compareTo(Kinga other) {
return Double.compare(this.d, other.d);
}
which means: I'm bigger than another Kinga if my d is bigger than the other Kinga's d.
PriorityQueue<kinga> will expect Comparable<kinga> in the add method. Passing a Comparable<Dobule> instead, is throwing ClassCastException
Can somebody tell me how comparable and priority queues work?
First get the difference between Comparable and Comparator interfaces.
Now for your question you can do something like below
First create a Comparator for Kinga
class comparableKinga implements Comparator<kinga> {
#Override
public int compare(kinga o1, kinga o2) {
return Double.compare(o1.getD(),o2.getD());
}
}
Then create your priority queue with this Comparator in the constructor
class kinga {
double d;
public kinga(double a) {
this.d = a;
}
public double getD() {
return this.d;
}
#Override
public String toString() {
return "kinga{" +
"d=" + d +
'}';
}
public static void main(String arg[]) {
PriorityQueue<kinga> r = new PriorityQueue<kinga>(11,new comparableKinga());
r.add(new kinga(4545.45));
r.add(new kinga(45.4));
r.add(new kinga(1235.45));
System.out.println(r.poll() + " " + r.poll() + " " + r.poll());
}
}
Output is as expected
kinga{d=45.4} kinga{d=1235.45} kinga{d=4545.45}

Categories

Resources