import java.util.*; /* interface Comparable<T> { int compareTo( T o ); } */ class Point implements Comparable<Point> { double x, y; Point( double x, double y ){ this.x = x; this.y = y; } public String toString(){ return x + "," + y; } public boolean equals( Object o ){ if( o != null && o instanceof Point ){ Point p = (Point) o; return x == p.x && y == p.y; } else return false; } private double distanceSquare(){ return x*x + y*y; } public int compareTo( Point p ){ return (int) Math.signum( distanceSquare() - p.distanceSquare() ); } } // class ColoredPoint extends Point implements Comparable<ColoredPoint> { ... } // illegal! violates subtyping? implementation problem? class ColoredPoint extends Point /* implements Comparable<Point> */ { int color; ColoredPoint( double x, double y, int color ){ super(x,y); this.color=color; } public String toString(){ return super.toString() + "/" + color; } public boolean equals( Object o ){ boolean se = super.equals(o); if( se && o instanceof ColoredPoint ){ return color == ((ColoredPoint)o).color; } else return se; } // public int compareTo( ColoredPoint p ){ ... } // this is overloading, not redefinition: this is not what we want public int compareTo( Point p ){ int d = super.compareTo(p); return (p instanceof ColoredPoint && d == 0) ? color - ((ColoredPoint)p).color : d; } } class G20_bad { public static <E extends Comparable<E>> E max( E[] array ){ E m = array[0]; for( int i=1; i<array.length; ++i ){ if( m.compareTo(array[i]) < 0 ){ m = array[i]; } } return m; } public static void main( String[] args ){ System.out.println( max(new Point[]{new Point(1,1), new Point(1,4), new Point(2,2)}) ); // System.out.println( max(new ColoredPoint[]{new ColoredPoint(1,1,2), new ColoredPoint(1,4,2), new ColoredPoint(2,2,2)}) ); } } class G20 { // still not perfect, but much better // wildcard with lower bound public static <E extends Comparable<? super E>> E max( E[] array ){ E m = array[0]; for( int i=1; i<array.length; ++i ){ if( m.compareTo(array[i]) < 0 ){ m = array[i]; } } return m; } public static <E extends Comparable<? super E>> E max( Collection<E> c ){ //public static <E extends Comparable<? super E>> E max( Collection<? extends E> c ){ // almost good... Iterator<E> it = c.iterator(); E m = it.next(); while( it.hasNext() ){ E e = it.next(); if( m.compareTo(e) < 0 ){ m = e; } } return m; } public static void main( String[] args ){ System.out.println( max(new Point[]{new Point(1,1), new Point(1,4), new Point(2,2)}) ); System.out.println( max(new ColoredPoint[]{new ColoredPoint(1,1,2), new ColoredPoint(1,4,2), new ColoredPoint(2,2,2)}) ); List<Point> lp = new ArrayList<Point>(); lp.add(new Point(1,1)); lp.add(new Point(1,4)); lp.add(new Point(2,2)); Set<ColoredPoint> scp = new HashSet<ColoredPoint>(); scp.add(new ColoredPoint(1,1,9)); scp.add(new ColoredPoint(1,4,2)); System.out.println( max(lp) ); System.out.println( max(scp) ); Collection<Collection<? extends Point>> cc = new LinkedList<Collection<? extends Point>>(); cc.add(lp); cc.add(scp); for( Collection<? extends Point> c: cc ){ System.out.println( max(c) ); } } }