-2

I'd like to implement a method that compares two Objects of my interface Task. Since there will only be a strict partial ordering on Task, partialCompareTo should return null if and only if the two objects are incomparable.

If you are confused by the concept of a strict partial ordering, check this out: https://en.wikipedia.org/wiki/Partially_ordered_set

Motivation: Some tasks will have the constraint that they have to be done before or after another task. This is then used to topological sort the tasks, i.e. arrange them in a way that all constraints are met.

It should have the following property, for any instances of Task a and b:

  • if a.partialCompareTo(b) != null then sgn(a.partialCompareTo(b)) = -sgn(b.partialCompareTo(a))
  • if a.partialCompareTo(b) = null then b.partialCompareTo(a) = null

Note: I can't use the interface Comparable of the standard library since there will be no total ordering on Task: compareTo in Comparable returns int, so there is no way for an adequate result if two objects are incomparable. In particular there will be implementations of Task, where instances of that implementations are never comparable to each other (but might be comparable to instances of other subclasses of Task, which override partialCompareTo).

The idea is to use the partialCompareTo method of the argument if it overrides the method specified in the class Task.

The following approach is actually more of a joke than an actual attempt, since every time two not comparable objects are compared we get an StackOverflowError (which is caught, but anyway this is not feasible):

public class Task implements TopologicalComparable<Task> {

    /*
     * other code
     */

    @Override
    public Integer partialCompareTo(Task other) {
        Integer result;
        try {
            result = - other.partialCompareTo(this);
        } catch (StackOverflowError | NullPointerException e) {
            return null;
        }
        return null;
    }

}

The following implementation is clearly better, but it has the downside, that one always has to override the helper method overridesDefaultPartialCompareTo:

public class Task implements TopologicalComparable<Task> {

    /*
     * other code
     */

    @Override
    public Integer partialCompareTo(Task other) {
        if (other.overridesDefaultPCompareTo()) {
            Integer revComp = other.overridesDefaultPartialCompareTo(this);
            if (revComp != null) {
                return - revComp;
            }
        }
        return null;
    }

    public default boolean overridesDefaultPartialCompareTo() {
        return false;
    }

}

Is there a way to ask, whether the method is overwritten in code?

Or is there an alternative approach to solve my problem?

  • You should be using the Comparable interface and write its behavior as Joshua Bloch recommends in "Effective Java". – duffymo Mar 05 '16 at 16:49
  • I can't use Comparable, since Comparable needs a total ordering, which I don't have at this point. Comparable returns an int, so there would be no way to have a result that means a and b are not comparable. – JTSkywalker Mar 05 '16 at 17:14

2 Answers2

0

when you compare things you should using something with a comparable interface as recommended by duffymo. To go into detail, you should be keeping your items in an ArrayList then overwriting the compare method. I am not sure why you have pCompare, but I am going to assume you do not understand inheritance and polymorphism. Instead of changing the name of your compare you should be using extends, here are documents about Inheritance please read them. It looks like your syntax is good, but your understanding of how java code is written is not good. So how should you do this?

Lets start with the first thing I think is wrong (feel free to correct me guys if this is incorrect) you are not using an interface correctly. An interface is good for declaring global variables, helping you implement design patterns, and ect. Most people say it is a contract of behavior. In plain English use an interface to help you get past Multiple Inheritance. I have no idea why you are using one and what you plan to do with it, but I have never added a method to an interface that is implemented.

The next thing is you renaming your pCompareTo I have never done that and I have helped make some pretty large programs. I really don't think it is good programming. It should be in a class. The class that uses it is fine, though not always, and I am having a hard time thinking of how it can be explained so you might have to do some research.

When you get rid of the interface, put compareTo() in the correct place (do not change it to pCompareTo() that is bad programming) you override it like you did, and specify what goes into it. Pay attention this is important Usually when you override a compare to you have the compareTo Method you have it return -1 if the object coming in is smaller than what it is being compared to, 1 if it is larger or 0 if it is the same size. In the case where you just want to check if it is equal then you can simply check if they are equal like for string you do

string1.equals(string2)

and it will return 1 if true or 0 if false.

 @Override
public default Integer pCompareTo(Task other) {
    Integer result;
    try {
        result = - other.pCompareTo(this);
    } catch (StackOverflowError | NullPointerException e) {
        return null;
    }
    return null;
}

Ok this is horribly wrong man, just horribly wrong. Your method is pCompareTo() right? You are calling it inside itself (that is called recursion and I would not recommend you using that right now). I do not know what you are comparing (also a you don't need a try catch here but can if you want to, a try catch is like a trap you set in your code that goes off if that particular area did not work correctly), but if they were integers you would do something like

@Override
public int compareTo(Integer other){
 if (this < other) {
  return 1;
 }
 if (this > other) {
  return -1;
 }
 return 0;

Please see override explanation. It is just to much for me to explain how it works to you in this already long post. Good luck, and my advice syntax in programming is not very important. Knowing how to program properly is much more important.

Community
  • 1
  • 1
  • Check out default methods! https://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html – JTSkywalker Mar 05 '16 at 18:21
  • I have clarified my post so it becomes more clear that I am not using the interface `Comparable` because it doesn't fit in my scenario. I also have kept out the default methods, since they are a Java 8 feature and arguably not very well known by most people. It doesn't change the problem though. – JTSkywalker Mar 05 '16 at 18:26
  • Those are setters though. I strongly encourage you to read hearfirst java, then head first design pattern – Jon_the_developer Mar 05 '16 at 18:33
  • That is not entirely true, you could do it with any method. But that is not the point. Do you mind checking my question again? I have clarified it to prevent further misconceptions. – JTSkywalker Mar 05 '16 at 18:39
  • Ok JT, it seems like you are intelligent, but you are not listening to me. You are not making your program correctly. When you have an interface with an overriden compare method that's comparable to riding a bicycle with a training wheel on one side. You are just straight up doing it wrong. I have a MS in CS man I know what I am talking about. Moving on, I will add another short answer. – Jon_the_developer Mar 05 '16 at 18:45
0

The revision is slightly better, and makes more sense. Thank you for that. Now to start off you need to understand that you are comparing objects. If you would like to write a compareTo() method you need to think about 'what am I comparing'. In order for you to write your method you need to explain to us what you are comparing, in your mind you might be comparing elements in a set. But in the programming world you are comparing ints, strings, or w/e you make them out of. So I ask you, what are you comparing? You should make a class of w/e you are comparing, say

class POsetElement{...
//make some sort of set element object
}

In this class you would want to implement comparable like so,

class POsetElement implements comparable{...
//make some sort of set element object...

//then make w/e other methods you need...

//now use compareTo() override
@override
compareTo(){
//make your custom method
}
}

Notice how I put the compareTo() method INSIDE the POsetElement class. Java is OOP. That means object oriented programming. You need to custom build objects. You need to make your own world,create your own objects. There is not way that I can explain all of this to you. Please put in some effort and learn more java programming. Also you need to understand I would say that these are some very basic things and once again I will reiterate that you need to read a bit on java basics. Good luck.

Community
  • 1
  • 1