// http://www.docjar.com/html/api/java/lang/String.java.html
import java.util.Arrays;
public final class MyString implements Comparable<MyString> {
    private final char value[]; // The value is used for character storage.
    private final int offset;// the first index of the storage that is used.
    private final int count; // number of characters in the String.
    private int hash; // Cache the hash code for the string
    /**
     * Initializes a newly created {@code String} object so that it represents
     * an empty character sequence. Note that use of this constructor is
     * unnecessary since Strings are immutable.
     */
    public MyString() {
        this.offset = 0;
        this.count = 0;
        this.value = new char[0];
    }
    /**
     * Initializes a newly created {@code String} object so that it represents
     * the same sequence of characters as the argument; in other words, the
     * newly created string is a copy of the argument string. Unless an explicit
     * copy of {@code original} is needed, use of this constructor is
     * unnecessary since Strings are immutable.
     *
     * @param original A {@code String}
     */
    public MyString(MyString original) {
        int size = original.count;
        char[] originalValue = original.value;
        char[] v;
        if (originalValue.length > size) {
            // The array representing the String is bigger than the new
            // String itself.  Perhaps this constructor is being called
            // in order to trim the baggage, so make a copy of the array.
            int off = original.offset;
            v = Arrays.copyOfRange(originalValue, off, off + size);
        } else {
            // The array representing the String is the same
            // size as the String, so no point in making a copy.
            v = originalValue;
        }
        this.offset = 0;
        this.count = size;
        this.value = v;
    }
    /**
     * Allocates a new {@code String} so that it represents the sequence of
     * characters currently contained in the character array argument. The
     * contents of the character array are copied; subsequent modification of
     * the character array does not affect the newly created string.
     *
     * @param value The initial value of the string
     */
    public MyString(char value[]) {
        int size = value.length;
        this.offset = 0;
        this.count = size;
        this.value = Arrays.copyOf(value, size);
    }
    /**
     * Compares this string to the specified object. The result is {@code
     * true} if and only if the argument is not {@code null} and is a {@code
     * String} object that represents the same sequence of characters as this
     * object.
     *
     * @param anObject The object to compare this {@code String} against
     *
     * @return {@code true} if the given object represents a {@code String}
     * equivalent to this string, {@code false} otherwise
     *
     * @see #compareTo(String)
     * @see #equalsIgnoreCase(String)
     */
    @Override
    public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof MyString) {
            MyString anotherString = (MyString) anObject;
            int n = count;
            if (n == anotherString.count) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = offset;
                int j = anotherString.offset;
                while (n-- != 0) {
                    if (v1[i++] != v2[j++]) {
                        return false;
                    }
                }
                return true;
            }
        }
        return false;
    }
    @Override
    public int compareTo(MyString anotherString) {
        int len1 = count;
        int len2 = anotherString.count;
        int n = Math.min(len1, len2);
        char v1[] = value;
        char v2[] = anotherString.value;
        int i = offset;
        int j = anotherString.offset;
        if (i == j) {
            int k = i;
            int lim = n + i;
            while (k < lim) {
                char c1 = v1[k];
                char c2 = v2[k];
                if (c1 != c2) {
                    return c1 - c2;
                }
                k++;
            }
        } else {
            while (n-- != 0) {
                char c1 = v1[i++];
                char c2 = v2[j++];
                if (c1 != c2) {
                    return c1 - c2;
                }
            }
        }
        return len1 - len2;
    }
    /**
     * Returns a hash code for this string. The hash code for a
     * <code>String</code> object is computed as
     * <blockquote><pre>
     * s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
     * </pre></blockquote>
     * using <code>int</code> arithmetic, where <code>s[i]</code> is the
     * <i>i</i>th character of the string, <code>n</code> is the length of the
     * string, and <code>^</code> indicates exponentiation. (The hash value of
     * the empty string is zero.)
     *
     * @return a hash code value for this object.
     */
    @Override
    public int hashCode() {
        int h = hash;
        if (h == 0 && count > 0) {
            int off = offset;
            char val[] = value;
            int len = count;
            for (int i = 0; i < len; i++) {
                h = 31 * h + val[off++];
            }
            hash = h;
        }
        return h;
    }
}
