Welcome to Dream.In.Code
Become a Java Expert!

Join 150,103 Java Programmers for FREE! Get instant access to thousands of Java experts, tutorials, code snippets, and more! There are 1,841 people online right now. Registration is fast and FREE... Join Now!




Implement Comparable interface for an inner class?

 
Reply to this topicStart new topic

Implement Comparable interface for an inner class?, how to implement interface for inner class, how to test it?

vangogh
23 Jun, 2008 - 09:44 AM
Post #1

New D.I.C Head
*

Joined: 30 May, 2008
Posts: 22

I need help on how to implement the Comparable interface for the private, inner class Date, which is in the Person class below. I was told its best to implement it at the lowest possible level to keep code as modular as possible. I think I did it correctly, but since Date is within Person, I have no idea how I would test it. If you could look at my code and see what I should do, I'd greatly appreciate it.

CODE

    public class Person
   {
      private String name;
      private Date born;
      private Date died;    //null indicates still alive.
  
  
       public Person(String initialName, int birthMonth, int birthDay,
                       int birthYear)
      {
            name = initialName;
         born = new Date(birthMonth, birthDay, birthYear);
         died = null;
      }
       
       public Person(String initialName, int birthMonth, int birthDay,
                       int birthYear, int deathMonth, int deathDay,
                       int deathYear)
      {
            name = initialName;
         born = new Date(birthMonth, birthDay, birthYear);
         died = new Date(deathMonth, deathDay, deathYear);
      }
       
       public String toString()
      {
         if (died == null)        
            return name+", "+born.toString()+" - ";
         return name+", "+born.toString()+" - "+died.toString();
      }
  
       private class Date implements Comparable
      {
         private int month, day, year;
      
          Date(int month, int day, int year)
         {
            this.month = month;
            this.day = day;
            this.year = year;
         }
      
            
            
          public int compareTo(Object other)
         {
            Date otherDate = (Date)other;
        
            if (this.precedes(otherDate))            return -1;
            else if (this.equals(otherDate))        return 0;
            return 1;
         }
      
      
          public boolean equals(Date otherDate)
         {
            if (otherDate == null)    
               return false;
            return (day == otherDate.getDay()) &&
                   (month == otherDate.getMonth()) &&
                  (year == otherDate.getYear());
         }
      
      
          public int getDay()
         {
            return day;
         }
      
          public int getMonth()
         {
            return month;
         }
      
          public int getYear()
         {
            return year;
         }
      
          
      /** Method to determine if this Date precedes another one.
      * @param otherDate - Date being compared
      * @return boolean - TRUE if this Date precedes otherDate
      */
          public boolean precedes(Date otherDate)
         {
            if(otherDate == null)
            {
               return true;
            }
        
            if (year < otherDate.getYear())
            {
               return true;
            }
            else if ((year == otherDate.getYear()) && (month < otherDate.getMonth()))
            {
               return true;
            }
            else if ((year == otherDate.getYear()) && (month == otherDate.getMonth()) && (day < otherDate.getDay()))
            {
               return true;
            }
            else        
               return false;  
         }
      
            public String toString()
            {
                return (month+"/"+day+"/"+year);
            }
      }
   }


the driver (, so far, because i don't know how to test the Comparable interface):
CODE

public class Tester
{
    public static void main(String[] args)
    {
        Person p1 = new Person("Bob", 2, 23, 1949, 11, 30, 2003);
        Person p2 = new Person("Alice", 3, 12, 1977, 1, 10, 1999);
        
        
        System.out.println(p1);
        System.out.println(p2);
    }
}

User is offlineProfile CardPM
+Quote Post

pbl
RE: Implement Comparable Interface For An Inner Class?
23 Jun, 2008 - 01:51 PM
Post #2

D.I.C Lover
Group Icon

Joined: 6 Mar, 2008
Posts: 3,587



Thanked: 233 times
Dream Kudos: 75
My Contributions
Add a static void main() method in your Person class
In this main() create a dummy person
Now thru this dummy person you can access Date constructor
Fill an array of Date and sort it
Then:

java Person

CODE

public static void main(String[] arg) {
    // create a dummy person so I can access Date
    Person p = new Person("xxx", 10, 10, 10);

    Date[] d = new Date[5];
    d[0] = p.new Date(1900, 10, 15);
    d[1] = p.new Date(1900, 1, 15);
    d[2] = p.new Date(2000, 10, 10);
    d[3] = p.new Date(1800, 1, 15);
    d[4] = p.new Date(1800, 1, 1);

    Arrays.sort(d);
    for(int i = 0; i < d.length; i++)
        System.out.println(d[i]);
}


User is offlineProfile CardPM
+Quote Post

vangogh
RE: Implement Comparable Interface For An Inner Class?
23 Jun, 2008 - 07:22 PM
Post #3

New D.I.C Head
*

Joined: 30 May, 2008
Posts: 22

okay, i see what to do now... but if you have to create a dummy person to make the Comparable interface useful for the Date class, then wouldn't it be better to just implement it for the Person class and sort a Person array. Is there any other practical application of using compareTo() and the Comparable interface in the Date class?
User is offlineProfile CardPM
+Quote Post

pbl
RE: Implement Comparable Interface For An Inner Class?
23 Jun, 2008 - 07:29 PM
Post #4

D.I.C Lover
Group Icon

Joined: 6 Mar, 2008
Posts: 3,587



Thanked: 233 times
Dream Kudos: 75
My Contributions
QUOTE(vangogh @ 23 Jun, 2008 - 08:22 PM) *

but if you have to create a dummy person to make the Comparable interface useful for the Date class, then wouldn't it be better to just implement it for the Person class and sort a Person array.


YOU are the one who asked for it. I tried to do exactly what you asked for.

QUOTE

I was told its best to implement it at the lowest possible level to keep code as modular as possible


I've just tried to implement your wishes biggrin.gif

But nothing should stop you to implement Comparable in Person and have Person compareTo() method to call Date compareTo() method
Then you will test the compareTo() method of the Person class not the CompareTo() method of the Date class ... that was your original request

This post has been edited by pbl: 23 Jun, 2008 - 08:22 PM
User is offlineProfile CardPM
+Quote Post

baavgai
RE: Implement Comparable Interface For An Inner Class?
24 Jun, 2008 - 04:41 AM
Post #5

Dreaming Coder
Group Icon

Joined: 16 Oct, 2007
Posts: 2,282



Thanked: 136 times
Dream Kudos: 475
Expert In: C, C++, Java, C#, ASP.NET, PHP, Perl, Python, Oracle, SQL Server, MySql, HTML, JavaScript, Lua, Cheese

My Contributions
I think the first question is, why should this be an inner class?

pbl is correct, if you want to test your inner Date, and you don't want it static, you have to do it from the parent. Here's another attack that does basically the same thing, in a slightly different way, with comments. Note, this example won't run on it's own, you can figure out what to add.

java

public class Person {
// the addition of a private constructor, for testing only.
private Person() {}
private class Date implements Comparable {
// I'd do all the work in the method, to avoid any redundancy.
public int compareTo(Object other) {
if (other==null) { return -1; }
if (!this.getClass().equals(other.getClass())) { return -1; }
Date otherDate = (Date)other;
// your code here
// hint, this is only six lines

return 0;
}

// use the compareTo you made.
// also, make this an object as well,
// you're overiding the default object method, which is what you want
public boolean equals(Object other) {
return compareTo(other)==0;
}
}

// your test method, INSIDE
private void testDate() {
Date[] dts = new Date[] {
new Date(10, 15, 1900),
new Date(10, 10, 2000),
new Date(1, 15, 1800),
new Date(1, 1, 1800)
};
Arrays.sort(dts);
for(Date dt : dts) {
System.out.println(dt);
}
}

public static void main (String[] args) {
// this main method is in Person class, so it can do this
new Person().testDate();
// other classes don't have access to either of those methods
}
}


Hope this helps.

User is offlineProfile CardPM
+Quote Post

vangogh
RE: Implement Comparable Interface For An Inner Class?
24 Jun, 2008 - 05:22 AM
Post #6

New D.I.C Head
*

Joined: 30 May, 2008
Posts: 22

alright, I get it now. Thanks pbl and baavgai. I appreciate it.

User is offlineProfile CardPM
+Quote Post

pbl
RE: Implement Comparable Interface For An Inner Class?
24 Jun, 2008 - 01:05 PM
Post #7

D.I.C Lover
Group Icon

Joined: 6 Mar, 2008
Posts: 3,587



Thanked: 233 times
Dream Kudos: 75
My Contributions
By the way if your Date had a method

CODE

int numValue() {
   return (year * 10000) + (month * 100) + day;
}


then your compare to would be

CODE

int compareTo(Object o) {
   return numValue() - ((Date) o).numValue();
}


I let you figure out the equals() and precedes() method


User is offlineProfile CardPM
+Quote Post

Fast ReplyReply to this topicStart new topic
Time is now: 1/9/09 12:44AM

Be Social

Dream.In.Code RSS Feed Dream.In.Code LinkedIn Group Follow Us On Twitter

Live Java Help!

Java Tutorials

Reference Sheets

Java Snippets

DIC Chatroom

Bye Bye Ads

Monthly Drawing

Thumb Drive

Top Contributors

Top 10 Kudos This Month