// --------
// Max.java
// --------

/*

package java.lang;

interface Comparable<T> {
    int compareTo (T value);}        // const

*/

/*

package java.util;

interface Comparator<T> {
    int compare (T value1, value2);} // const

*/

import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;

class A implements Comparable<A> {
    private int i;

    public A (int j) {
        i = j;}

    public int compareTo (A that) {
        return i - that.i;}

    public boolean equals (Object that) {
        return i == ((A) that).i;}}

class B extends A {
    public B (int k) {
        super(k);}}

final class Max {
    /**
     * O(1) in space
     * O(n) in time
     */
    public static long eval (long[] a, int b, int e) {
        assert b < e;
        long m = a[b];
        ++b;
        while (b != e) {
            final long n = a[b];
            if (m < n)
                m = n;
            ++b;}
        return m;}

    /**
     * O(1) in space
     * O(n) in time
     */
    public static <T extends Comparable<? super T>> T eval (T[] a, int b, int e) {
        assert b < e;
        T m = a[b];
        ++b;
        while (b != e) {
            final T n = a[b];
            if (m.compareTo(n) < 0)
                m = n;
            ++b;}
        return m;}

    /**
     * O(1) in space
     * O(n) in time
     */
    public static <T> T eval (T[] a, int b, int e, Comparator<? super T> c) {
        assert b < e;
        T m = a[b];
        ++b;
        while (b != e) {
            final T n = a[b];
            if (c.compare(m, n) < 0)
                m = n;
            ++b;}
        return m;}

    /**
     * O(1) in space
     * O(n) in time
     */
    public static <T extends Comparable<? super T>> T eval (Collection<? extends T> x) {
        Iterator<? extends T> p = x.iterator();
        T                     m = p.next();
        while (p.hasNext()) {
            final T n = p.next();
            if (m.compareTo(n) < 0)
                m = n;}
        return m;}

    /**
     * O(1) in space
     * O(n) in time
     */
    public static <T> T eval (Collection<? extends T> x, Comparator<? super T> c) {
        Iterator<? extends T> p = x.iterator();
        T                     m = p.next();
        while (p.hasNext()) {
            final T n = p.next();
            if (c.compare(m, n) < 0)
                m = n;}
        return m;}}

final class StringReverseComparator implements Comparator<String> {
    public int compare (String x, String y) {
        return y.compareTo(x);}}

final class AReverseComparator implements Comparator<A> {
    public int compare (A x, A y) {
        return y.compareTo(x);}}

final class MaxTest {
    public static void main (String[] args) {
        System.out.println("Max.java");

        {
        final long[] a = {2, 3, 4};
        final long   x = Max.eval(a, 0, a.length);
        assert x == 4;
        }

        {
        final String[] a = {"abc", "def", "ghi"};
        final String   x = Max.eval(a, 0, a.length);
        assert x == "ghi";
        }

        {
        final Comparator<String> c =
            new Comparator<String> () {
                public int compare (String x, String y) {
                    return x.compareTo(y);}};
        final String[] a = {"abc", "def", "ghi"};
        final String   x = Max.eval(a, 0, a.length, c);
        assert x == "ghi";
        }

        {
        final Comparator<String> c = new StringReverseComparator();
        final String[] a = {"abc", "def", "ghi"};
        final String   x = Max.eval(a, 0, a.length, c);
        assert x == "abc";
        }

        {
        final A[] a = {new A(2), new A(3), new A(4)};
        final A   x = Max.eval(a, 0, a.length);
        assert x.equals(new A(4));
        final B[] b = {new B(5), new B(6), new B(7)};
        final B   y = Max.eval(b, 0, b.length);
        assert y.equals(new B(7));
        }

        {
        final Comparator<A> c =
            new Comparator<A> () {
                public int compare (A x, A y) {
                    return x.compareTo(y);}};
        final A[] a = {new A(2), new A(3), new A(4)};
        final A   x = Max.eval(a, 0, a.length, c);
        assert x.equals(new A(4));
        final B[] b = {new B(5), new B(6), new B(7)};
        final A   y = Max.eval(b, 0, b.length, c);
        assert y.equals(new B(7));
        }

        {
        final Comparator<A> c = new AReverseComparator();
        final A[] a = {new A(2), new A(3), new A(4)};
        final A   x = Max.eval(a, 0, a.length, c);
        assert x.equals(new A(2));
        final B[] b = {new B(5), new B(6), new B(7)};
        final A   y = Max.eval(b, 0, b.length, c);
        assert y.equals(new B(5));
        }

        {
        final Collection<String> x = Arrays.asList("abc", "def", "ghi");
        final String             y = Collections.max(x);
        assert y == "ghi";
        }

        {
        final Collection<String> x = Arrays.asList("abc", "def", "ghi");
        final String             y = Max.eval(x);
        assert y == "ghi";
        }

        {
        final Comparator<String> c =
            new Comparator<String> () {
                public int compare (String x, String y) {
                    return x.compareTo(y);}};
        final Collection<String> x = Arrays.asList("abc", "def", "ghi");
        final String             y = Collections.max(x, c);
        assert y == "ghi";
        }

        {
        final Comparator<String> c =
            new Comparator<String> () {
                public int compare (String x, String y) {
                    return x.compareTo(y);}};
        final Collection<String> x = Arrays.asList("abc", "def", "ghi");
        final String             y = Max.eval(x, c);
        assert y == "ghi";
        }

        {
        final Comparator<String> c = new StringReverseComparator();
        final Collection<String> x = Arrays.asList("abc", "def", "ghi");
        final String             y = Collections.max(x, c);
        assert y == "abc";
        }

        {
        final Comparator<String> c = new StringReverseComparator();
        final Collection<String> x = Arrays.asList("abc", "def", "ghi");
        final String             y = Max.eval(x, c);
        assert y == "abc";
        }

        {
        final Collection<A> a = Arrays.asList(new A(2), new A(3), new A(4));
        final A             x = Collections.max(a);
        assert x.equals(new A(4));
        final Collection<B> b = Arrays.asList(new B(5), new B(6), new B(7));
        final B             y = Collections.max(b);
        assert y.equals(new B(7));
        }

        {
        final Collection<A> a = Arrays.asList(new A(2), new A(3), new A(4));
        final A             x = Max.eval(a);
        assert x.equals(new A(4));
        final Collection<B> b = Arrays.asList(new B(5), new B(6), new B(7));
        final B             y = Max.eval(b);
        assert y.equals(new B(7));
        }

        {
        final Comparator<A> c =
            new Comparator<A> () {
                public int compare (A x, A y) {
                    return x.compareTo(y);}};
        final Collection<A> a = Arrays.asList(new A(2), new A(3), new A(4));
        final A             x = Collections.max(a, c);
        assert x.equals(new A(4));
        final Collection<B> b = Arrays.asList(new B(5), new B(6), new B(7));
        final B             y = Collections.max(b, c);
        assert y.equals(new B(7));
        }

        {
        final Comparator<A> c =
            new Comparator<A> () {
                public int compare (A x, A y) {
                    return x.compareTo(y);}};
        final Collection<A> a = Arrays.asList(new A(2), new A(3), new A(4));
        final A             x = Max.eval(a, c);
        assert x.equals(new A(4));
        final Collection<B> b = Arrays.asList(new B(5), new B(6), new B(7));
        final B             y = Max.eval(b, c);
        assert y.equals(new B(7));
        }

        {
        final Comparator<A> c = new AReverseComparator();
        final Collection<A> a = Arrays.asList(new A(2), new A(3), new A(4));
        final A             x = Collections.max(a, c);
        assert x.equals(new A(2));
        final Collection<B> b = Arrays.asList(new B(5), new B(6), new B(7));
        final B             y = Collections.max(b, c);
        assert y.equals(new B(5));
        }

        {
        final Comparator<A> c = new AReverseComparator();
        final Collection<A> a = Arrays.asList(new A(2), new A(3), new A(4));
        final A             x = Max.eval(a, c);
        assert x.equals(new A(2));
        final Collection<B> b = Arrays.asList(new B(5), new B(6), new B(7));
        final B             y = Max.eval(b, c);
        assert y.equals(new B(5));
        }

        System.out.println("Done.");}}


syntax highlighted by Code2HTML, v. 0.9.1