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) );
    }

  }

}