0

Suppose we have a Java type called Contract which represents business contracts. Among the method headers in class Contract are the following:

public Date finish()

returns an object representing the date on which a contract finishes.

public void update(Date d)

changes the state of the object on which it is called to represent changes in contract terms which apply after the date given by the argument.

public int payment(Date d)

returns the payment due on the date given as its argument, this will always be an integer which is greater than 0.

public Set<Contract> subcontracts()

returns a set representing all the subcontracts of the contract represented by the object on which this method is called.

One of the questions asked:

Write an instance method to go in class Contract called biggestPayment. When called on an object representing a contract, this method should take a Date argument and return the representation of whichever subcontract has the biggest payment due on the date given. If the contract has no subcontracts, the object on which the method is called should be returned.

My first problem is I can't figure out how to return the Contract object with the max value..or if the contract has no subcontracts, the object on which the method is called should be returned...

Here's what I have so far.. but it doesn't like that I called method payment from the inner class:

public Contract biggestPayment(Date d)
{

List<Contract> clist = new ArrayList<Contract>(subc);
Collections.sort(clist, new Comparator<Contract>() 
{
       public int compare(Contract c1, Contract c2) 
       {
          c1.payment(d).compareTo(c2.payment(d));
       }
});


 .......
}

Any help would be appreciated.

nothingme
  • 55
  • 1
  • 8

1 Answers1

1

The Date d argument has got to be final in order to be able to use it in an anonymous subclass.

public Contract biggestPayment(final Date d) {

Also make sure to invoke the compare() method on Integers and not ints. Being int a primitive type, you cannot invoke any method on it. You could either wrap them up in Integers and invoke compare, or compare the ints yourself and return the result according to Comparator#compare()'s contract.

Remember that using local variables from an outer scope in an anonymous subclass requires the variable to be final. Here is why: Why are only final variables accessible in anonymous class?.

The variable will be effectively passed in as a reference to the subclass.

So, doing this:

final Date d;
new Comparator<Contract>() {
    public int compare(Contract c1, Contract c2) {
        c1.payment(d).compareTo(c2.payment(d));
    }
};

is roughly equivalent to

Date d;
new MyComparator(d);

private final class MyComparator implements Comparator<Contract> { 
    Date dueDate;
    public MyComparator(Date aDate) {
        this.dueDate = aDate;
    }
    public int compare(Contract c1, Contract c2) {
        c1.payment(dueDate).compareTo(c2.payment(dueDate));
    }
}
Community
  • 1
  • 1
Xavi López
  • 27,550
  • 11
  • 97
  • 161
  • I added the final to the argument... But I got an error saying int cannot be dereferenced for the line because payment returns in not object...: c1.payment(d).compareTo(c2.payment(d)); – nothingme May 16 '13 at 11:25
  • So I used: return new Integer( c1.payment(d) ).compareTo( new Integer (c2.payment(d)) ); – nothingme May 16 '13 at 11:34
  • That's right, `int` being a primitive type, it isn't an `Object` and therefore doesn't have the `compare` method. You could also have returned `0`, `1` or `-1` by comparing the `int`s yourself. Edited the answer to reflect this. – Xavi López May 16 '13 at 11:37
  • I did this : return clist.get(clist.size() - 1); which will return the biggest contract after it's is sorted... I was just wondering.. why is return new Integer( c1.payment(d) ).compareTo( new Integer (c2.payment(d)) ) correct...isn't it returning new Integer instead of the required type - Contract for the method – nothingme May 16 '13 at 11:46
  • The `compare` method's contract specifies that its return type is an `int`, with the value `0` if both arguments are considered equal, `1` if the first argument is greater than the second, and `-1` if the first argument is lower than the second. That's exactly what the `Integer#compare()` method returns. Take into account that the `return` in the `compare()` method isn't the `return` of your `biggestPayment` method. `Collections.sort` sorts the list automatically according to the sort criteria specified by the `Comparator`. – Xavi López May 16 '13 at 11:49
  • sorry, One more question.. when the question asked - "If the contract has no subcontracts, the object on which the method is called should be returned." What does it mean? Do I just make an if statement checking if the set is Null? – nothingme May 16 '13 at 13:08
  • Indeed, I'd explicitly check if `subcontracts()` is `null` or empty in first place. If it is null just `return this`. – Xavi López May 16 '13 at 13:35