The Java Tutorials Comparable and Comparator. Object Ordering A List may be sorted as follows. Collections.sort(l); If the List consists of String elements,

Slides:



Advertisements
Similar presentations
SUMMARY: abstract classes and interfaces 1 Make a class abstract so instances of it cannot be created. Make a method abstract so it must be overridden.
Advertisements

Problem Solving 5 Using Java API for Searching and Sorting Applications ICS-201 Introduction to Computing II Semester 071.
Singleton vs utility class  at first glance, the singleton pattern does not seem to offer any advantages to using a utility class  i.e., a utility class.
Using interfaces Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling How would you find the maximum.
CSE 143 Lecture 17 Binary Search Trees and Comparable slides created by Ethan Apter
Searching. 2 Searching an array of integers If an array is not sorted, there is no better algorithm than linear search for finding an element in it static.
Searching and Sorting I 1 Searching and Sorting 1.
Comparable and Comparator Nuts and Bolts. 2 Nuts and bolts Four methods underlie many of Java’s important Collection types: equals, compare and compareTo,
Unit 261 Introduction to Searching and Sorting Comparable Interface Comparator Interface Algorithm Complexity Classes Exercises.
Comparable and Comparator. Outline of the Student class import java.util.*; public class Student implements Comparable { public Student(String name, int.
ICS201 Lecture 20 : Searching King Fahd University of Petroleum & Minerals College of Computer Science & Engineering Information & Computer Science Department.
Searching. 2 Searching an array of integers If an array is not sorted, there is no better algorithm than linear search for finding an element in it static.
1 Introduction to Searching and Sorting Comparable Interface -Reading p Comparator Interface.
Unit 261 Introduction to Searching and Sorting Comparable Interface Comparator Interface Algorithm Complexity Classes Exercises.
Searching. Searching an array of integers If an array is not sorted, there is no better algorithm than linear search for finding an element in it static.
Introduction to Searching and Sorting
Chapter 22 Sets and Maps. Chapter Scope The Java API set and map collections Using sets and maps to solve problems How the Java API implements sets and.
Comparable and Comparator. 2 Comparing our own objects The Object class provides public boolean equals(Object obj) and public int hashCode() methods –For.
Comparing Objects in Java. The == operator When you define an object, for instance Person p = new Person("John", 23); we talk about p as if its value.
Searching Also: Logarithms. 2 Searching an array of integers If an array is not sorted, there is no better algorithm than linear search for finding an.
Set, TreeSet, TreeMap, Comparable, Comparator. Def: The abstract data type set is a structure that holds objects and satifies ARC: Objects can be added.
CS-2851 Dr. Mark L. Hornick 1 Tree Maps and Tree Sets The JCF Binary Tree classes.
Object Oriented Design and UML
Searching Also: Logarithms. 2 Searching an array of integers If an array is not sorted, there is no better algorithm than linear search for finding an.
Introduction to Testing 1. Testing  testing code is a vital part of the development process  the goal of testing is to find defects in your code  Program.
Goals for Today  implement a Deck of Cards  composition  Iterator interface  Iterable interface 1.
Lecture 8: Object-Oriented Design. 8-2 MicrosoftIntroducing CS using.NETJ# in Visual Studio.NET Objectives “Good object-oriented programming is really.
Generic abstraction  Genericity  Generic classes  Generic procedures Programming Languages 3 © 2012 David A Watt, University of Glasgow.
CSE 143 Lecture 15 Binary Search; Comparable reading: 13.2; 10.2 slides created by Marty Stepp
Chapter 13 Sets and Maps Modified. Chapter Scope The Java API set and map collections Using sets and maps to solve problems How the Java API implements.
Chapter 18 Java Collections Framework
Topic 1 Object Oriented Programming. 1-2 Objectives To review the concepts and terminology of object-oriented programming To discuss some features of.
Visual C# 2012 for Programmers © by Pearson Education, Inc. All Rights Reserved.
CIS3023: Programming Fundamentals for CIS Majors II Summer 2010 Ganesh Viswanathan Generics and Collections Course Lecture Slides 19 th July 2010 “Never.
Mixing Static and Non-static
HashCode() 1  if you override equals() you must override hashCode()  otherwise, the hashed containers won't work properly  recall that we did not override.
Comparable and Comparator Nuts and Bolts. Sets A set is a collection in which all elements are unique—an element is either in the set, or it isn’t In.
1 CSC 222: Computer Programming II Spring 2005 Java interfaces & polymorphism  Comparable interface  defining an interface  implementing an interface.
CS 61B Data Structures and Programming Methodology July 2, 2008 David Sun.
Polymorphism Liskov 8. Outline equals() Revisiting Liskov’s mutable vs. not rule Polymorphism Uniform methods for different types “easy” polymorphism.
U n i v e r s i t y o f H a i l 1 ICS 202  2011 spring  Data Structures and Algorithms 
Collections Mrs. C. Furman April 21, Collection Classes ArrayList and LinkedList implements List HashSet implements Set TreeSet implements SortedSet.
Interfaces and Inner Classes
Polymorphism SWE 619. Outline equals() Revisiting Liskov’s mutable vs. not rule Polymorphism Uniform methods for different types “easy” polymorphism Element.
Topic 1 Object Oriented Programming. 1-2 Objectives To review the concepts and terminology of object-oriented programming To discuss some features of.
Copyright © 2007 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Data Structures in Java: From Abstract Data Types to the Java Collections.
Java How to Program, 9/e © Copyright by Pearson Education, Inc. All Rights Reserved.
Puzzle 2 1  what does the following program print? public class Puzzle02 { public static void main(String[] args) { final long MICROS_PER_DAY = 24 * 60.
Exam 2 EXAM 2 Thursday!!! 25% of Final Grade Know: loops, switch/case Files Input failure (e.g. scan.hasNextInt())
1 CSE 331 Comparing objects; Comparable, compareTo, and Comparator slides created by Marty Stepp based on materials by M. Ernst, S. Reges, D. Notkin, R.
More constructors 1. Constructors  recall that a public constructor is what a client uses to create an object  the purpose of a constructor is to initialize.
(C) 2010 Pearson Education, Inc. All rights reserved. Java How to Program, 8/e.
12-CRS-0106 REVISED 8 FEB 2013 CSG2H3 Object Oriented Programming.
1 clone() Defined in Object Creates an identical copy –Copies pointers to fields (does not copy fields of fields) –Makes a shallow copy if the object’s.
Searching.
Chapter 5 Ordered List.
Chapter 21 Heaps and Priority Queues
Introduction to Searching and Sorting
Comparable and Comparator Interfaces
Comparable and Comparator
CSE 1030: Implementing Mixing static and non-static features
Outline Late Binding Polymorphism via Inheritance
Comparable and Comparator
CHAPTER 11: Priority Queues and Heaps
Searching.
Creating and Modifying Text part 3
TCSS 143, Autumn 2004 Lecture Notes
CS 240 – Advanced Programming Concepts
Comparable and Comparator Interfaces
Chapter 21 Heaps and Priority Queues
Presentation transcript:

The Java Tutorials Comparable and Comparator

Object Ordering A List may be sorted as follows. Collections.sort(l); If the List consists of String elements, it will be sorted into alphabetical order. If it consists of Date elements, it will be sorted into chronological order. String and Date both implement the Comparable interface. Comparable implementations provide a natural ordering for a class, which allows objects of that class to be sorted automatically.

Summary of a few Java platform classes that implement Comparable. ByteSigned numerical CharacterUnsigned numerical LongSigned numerical IntegerSigned numerical ShortSigned numerical DoubleSigned numerical FloatSigned numerical BigIntegerSigned numerical BigDecimalSigned numerical BooleanBoolean.FALSE < Boolean.TRUE StringLexicographic DateChronological

Collections.sort(list) will throw a ClassCastException if the objects in the list are not Comparable. Collections.sort(list, comparator) will throw a ClassCastException if the objects in the list are not compatible with the Comparator.

Writing Your Own Comparable Types The Comparable interface consists of the following method. public interface Comparable { public int compareTo(T o); } Where, compareTo compares the receiving object with the specified object and returns a negative integer if the receiving object is less than the specified object 0, if the receiving object is equal to the specified object positive integer if the receiving object is greater than the specified object If the specified object cannot be compared to the receiving object, the method throws a ClassCastException.

Example import java.util.*; public class Name implements Comparable { private final String firstName, lastName; public Name(String firstName, String lastName) { if (firstName == null || lastName == null) throw new NullPointerException(); this.firstName = firstName; this.lastName = lastName; } public String firstName(){return firstName;} public String lastName() {return lastName;} public boolean equals(Object o) { if (!(o instanceof Name)) return false; Name n = (Name) o; return n.firstName.equals(firstName) && n.lastName.equals(lastName); } public int hashCode() { return 31*firstName.hashCode() + lastName.hashCode(); } public String toString() { return firstName + " " + lastName; } public int compareTo(Name n) { int lastCmp = lastName.compareTo(n.lastName); return (lastCmp != 0 ? lastCmp : firstName.compareTo(n.firstName)); }

Typical Implementation of compareTo First, compare the most significant part of the object Often, you can just use the natural ordering of the part's type. In the example this part was lastName, a String, so the natural (lexicographic) ordering could be used. If the comparison results in anything other than zero, which represents equality, just return the result. If the most significant parts are equal, compare the next most- significant parts in the same manner. Proceed until you find two parts that are not equal or you reach the last comparison at which point you'd return the result of the comparison.

Client program example import java.util.*; public class NameSort { public static void main(String[] args) { Name nameArray[] = { new Name("John", "Smith"), new Name("Karl", "Ng"), new Name("Jeff", "Smith"), new Name("Tom", "Rich") }; List names = Arrays.asList(nameArray); Collections.sort(names); System.out.println(names); } If you run this program, here's what it prints. [Karl Ng, Tom Rich, Jeff Smith, John Smith]

Example from Lab public class PrioritizedObject implements Comparable { private static int nextOrder = 0; private int priority; private int arrivalOrder; private T element; public PrioritizedObject(T element, int priority) { this.element = element; this.priority = priority; arrivalOrder = nextOrder; nextOrder++; } /** * Returns 1 if the this object has higher priority than * the given object and -1 otherwise. * obj the object to compare to this node the result of the comparison of the given object * and this one */ public int compareTo(PrioritizedObject obj) { int result; if (priority > obj.getPriority()) result = 1; else if (priority < obj.getPriority()) result = -1; else if (arrivalOrder > obj.getArrivalOrder()) result = 1; else result = -1; return result; }

There are four restrictions on the behavior of the compareTo method, which we are not covered here but can be read in the API documentation.

Comparators Comparators are used for Sorting objects in an order other than their natural ordering Sorting objects that don't implement Comparable To do either of these things, you'll need to provide a Comparator — an object that encapsulates an ordering. Like the Comparable interface, the Comparator interface consists of a single method. public interface Comparator { int compare(T o1, T o2); } Like the compareTo method of the Comparable interface, the compare method of the Comparator interface compares its two arguments, returning a negative integer, 0, or a positive integer depending on whether the first argument is less than, equal to, or greater than the second. If either of the arguments has an inappropriate type for the Comparator, the compare method throws a ClassCastException.

Comparable compared to Comparator Much of what was said about Comparable applies to Comparator as well. Writing a compare method is nearly identical to writing a compareTo method, except that the former gets both objects passed in as arguments. The compare method has to obey the same four technical restrictions as Comparable's compareTo method for the same reason — a Comparator must induce a total order on the objects it compares.

Motivational Example Suppose you have a class called Employee, as follows. public class Employee implements Comparable { public String lastName() {... } public int number() {... } public Date hireDate() {... }... } Most times the sorted order should be by last name and then first name. The strategy of the previous example works would work for this ordering. But what if the ordering needed is not this order, but instead a list of employees in order of seniority is wanted.

Comparator Example import java.util.*; public class EmpSort { static final Comparator SENIORITY_ORDER = new Comparator () { public int compare(Employee e1, Employee e2) { return e2.hireDate().compareTo(e1.hireDate()); } }; static final Collection employees =...; public static void main(String[] args) { List e = new ArrayList (employees); Collections.sort(e, SENIORITY_ORDER); System.out.println(e); } Notes: This Comparator relies on the natural ordering of Date applied to the values returned by the hireDate accessor method. The Comparator passes the hire date of its second argument to its first rather than vice versa. The reason is that the employee who was hired most recently is the least senior; sorting in the order of hire date would put the list in reverse seniority order.

FYI: Achieving Seniority Order Another technique people sometimes use to achieve this effect is to maintain the argument order but to negate the result of the comparison – But this is NOT Reliable and should not be used. return e1.number() - e2.number(); However, this is not guaranteed to work. The reason for this is that the compareTo method can return any negative int if its argument is less than the object on which it is invoked. There is one negative int that remains negative when negated, strange as it may seem. -Integer.MIN_VALUE == Integer.MIN_VALUE

Comparator Example Deficiency The Comparator in the preceding program works fine for sorting a List, but it does have one deficiency: It cannot be used to order a sorted collection, such as TreeSet, because it generates an ordering that is not compatible with equals. This Comparator equates objects that the equals method does not. In particular, any two employees who were hired on the same date will compare as equal. When you're sorting a List, this doesn't matter; but when you're using the Comparator to order a sorted collection, it's fatal. If you use this Comparator to insert multiple employees hired on the same date into a TreeSet, only the first one will be added to the set; the second will be seen as a duplicate element and ignored.

Tweaking Comparator so that it produces an ordering that is compatible with equals. Goal: The only elements seen as equal when using compare are those that are also seen as equal when compared using equals. The way to do this is to perform a two-part comparison The first part is the one we're interested in, i.e. the hire date The second part is an attribute that uniquely identifies the object, i.e. employee id.

A Comparator that produces an ordering compatible with equals static final Comparator SENIORITY_ORDER = new Comparator () { public int compare(Employee e1, Employee e2) { int dateCmp = e2.hireDate().compareTo(e1.hireDate()); if (dateCmp != 0) return dateCmp; return (e1.number() < e2.number() ? -1 : (e1.number() == e2.number() ? 0 : 1)); } };

FYI: Numerical Inaccuracies One last note: You might be tempted to replace the final return statement in the Comparator with the simpler: return e1.number() - e2.number(); Consider the case of negative employee numbers.. Also consider that the signed integer type is not big enough to represent the difference of two arbitrary signed integers. If i is a large positive integer and j is a large negative integer, i - j will overflow and return a negative integer. The resulting comparator violates one of the four technical restrictions we keep talking about (transitivity) and produces horrible, subtle bugs. This is not a purely theoretical concern; people get burned by it.

References

import java.util.*; import jsjf.*; public class PQ { public static void main(String[] args) { MaxHeapComparator cmp = new MaxHeapComparator (); ArrayHeap pq = new ArrayHeap (cmp); Scanner scan = new Scanner(System.in); System.out.print("Enter an integer or q to quit "); String v = scan.next(); while(!v.equals("q")) { int priority = Integer.parseInt(v); pq.addElement(priority); System.out.println("okay " + priority + " tossed onto the heap."); System.out.print("Enter a value or q to quit "); v = scan.next(); } System.out.println("popping the values from the Heap"); while (!pq.isEmpty()) System.out.println(pq.removeTop()); scan.close(); }