Useful methods for Reference Type Classes


Contents

Introduction

    When you apply your abstract data structure to a real life situation, the data, which in the data structure is of type Object, can be anything of reference type. Quite often it is some class that you define. In order to work effectively with your class, you need to check, if two instances of your class are equal, you need to be able to print your class instances and sometimes you need to compare two instances. There are Java defined methods for these operations for the String class for example, and you can look them up in the Java API.
    For classes defined by you, you need to write these methods yourself.
 

Example:  the Employee class:

    This class has two fields, the name of the employee of type String, and the id number of type int.

    public class Employee{
        //fields
        String name;    //the name of the employee
        int id;              //the id number

        //constructors
        public Employee(String n, int i){
            name = n;
            id = i;
        }

        //the default constructor
        public Employee(){
            this(null, 0);        //this refers to the constructor above with the arguments null and 0
        }

        //other methods here
 

    }//Employee
 

The equals method

    Next we create two instances of the Employee class:

            Employee e1 = new Employee("Sarah Michaels", 1234);
            Employee e2 = new Employee("Sarah Michaels", 1234);

        We would like to test if e1 and e2 correspond field by field and for that we need
        to implement an equals methodfor the Employee class.

    Code:

        public boolean equals(Object ob){
              if (! ob instanceof  Employee) return false;        //1
              Employee e = (Employee)ob;                                            //2
             if (e.name.equals(name)&&e.id==id) return true;  //3
                //Alternatively we could code:
                // if (e.name.equals(this.name)&&e.id==this.id) return true;
                        //this refers to the calling instance
              return false;                                   //4
     }//equals

   Note:
            -    the argument is of type Object, so as to make the method more robust.
            -    in 1  we test if the argument is of type Employee
            -    in 2  we cast the argument, which we know is of type Employee, to Employee
            -    in 3  we compare the name and id fields, name is of type String, hence the .equals.
                  id is of type int, a primitive type, and we can use ==.
            -    if you are still around to execute 4, you should return false, because
                 the fields don't match.

Self Test 1:
            what would be the outcome of the test: true or false?    if (e1 == e2)...
 

the toString method:

        Usually we would like some feedback in form of printed data to a file/xterm window.
        In order for some generic print statements to work, like

               myOut.println(temp.data);    //here myOut refers to a PrintWriter
                                                                      //and temp.data refers to some instance of the Employee class

        we need to convert the data, contained in instances of our Employee class,  to String.
        If the instance that is stored at temp.data belongs to a class, that has a toString method,
        then the conversion  is done dynamically at runtime.
        This is very elegant, since we do not need to mention the Employee class inside the
        data structure program, which would be a terminal flaw in any general purpose data structure program.

     Code:

            public String toString(){
                return name+", "+id+"\n";
      }// toString

      Note:
            -    this will return a String containing  name and id separated by a comma and a space,
                  and ending with a carriage return.

the compareTo method

        If you want to store a class instance in a binary search tree, you need to introduce an
        ordering on the class instances.
        This could be done in many ways for the Employee class.
        You could order the instances by ordering their names in the dictionary order:
            Abby comes before Peter, because A comes before P.
        Or you could order them by their id number, or you could introduce an ordering of your own devising.
        In any case, you need to implement a method that allows you to compare the calling instance with
        another class instance and that returns:
           -    0, if the instances are the same;
           -    1, if the calling instance is the larger of the two;
           -    -1, if the calling instance is the smaller of the two.

    Code:

            public int compareTo(Object ob)throws ClassCastException{
                if (!(ob instanceof  Employee)) throw new ClassCastException();
                Employee e = (Employee) ob;
                if (id > e.id) return 1;
                if (id == e.id) return 0;
                return -1;
       }//compareTo

    Note:
        -    the ClassCastException is part of the Java Api and does not have to be written by you.

        In order to make effective use of the compareTo method, we must make the Employee class an
        extension of the Comparable interface.
        The Comparable interface is an abstract class of the java language, which does not implement
        its only method, the compareTo method. You do not need to code the Comparable class, it is already
        done for you in the java language. Here it is anyway:

        public abstract interface Comparable
        {
                public int compareTo(Object o);
        }

        Since the Employee class, with the inclusion of the compareTo method,
        implements the Comparable interface, we should state that in the header line
        of the Employee class:

        public class Employee implements Comparable{...}

        Then every time, a data structure (e.g. a binary search tree) program requires its data objects to
        be of type Comparable, Employee qualifies and it can be used in conjunction with the data structure.
 

the hashCode method

        If you want to store instances of the Employee class in a hash table, you need to find some
        way of converting the data in the Employee instances to some numerical (int) value.
        This is done by the hash function. You can read the lecture notes on reasonable ways of converting
        strings into integers. In  this implementation of the hashCode method we return as hash value the
        sum of id and the result of applying the String method hashCode  to name.

    public int hashCode(){
        return id + name.hashCode();
   }
 

Answer to Self Test problem:

1.    false,
        if (e1 == e2) tests whether e1 and e2 are stored in the same memory location,
        which is much more stringent than testing if they coincide field by field.