A ver, es muy sencillo.
Si tenemos esta situación:
String s1 = new String("hola");
String s2 = new String("hola");
String s3 = s2;
Aquí tenemos 3 variables: s1, s2 y s3. Si queremos saber si dos variables representan _el_mismo_objeto_, usamos ==. Esto es aplicable para cualquier tipo de objeto.
if (s1 == s2) ...
esto devuelve false, porque s1 y s2 son objetos distintos. Hemos creado s1 como una new String y luego s2 como otra new String.
if((s2 == s3) ...
esto devuelve true porque s2 y s3 realmente representan el mismo objeto (fíjate que hemos creado s3 asignándole s2 directamente, así que está claro que son el mismo objeto.
Ahora, tenemos en cuenta que los objetos que tenemos son String, y decidimos que lo que queremos saber no es si son el mismo objeto, sino si la cadena de texto que contienen es la misma. Entonces, para esto, String tiene un método llamado equals.
if (s1.equals(s2)) ...
Esto, al contrario que antes con ==, devuelve true, porque aunque no sea el mismo objeto, las cadenas que contienen sí que son iguales.
Hay que pensar que un objeto String es _más_ que la cadena que contiene. Es esa cadena y toda una serie de propiedades y métodos asociados al objeto. Por eso no es lo mismo comparar los objetos que sus valores.
--------------------------------------------------
compareTo. Este método va más allá de equals y sólo lo usaremos si realmente hace falta.
Es decir, equals sólo compara si son iguales o no. devuelve true o false y nada más. compareTo se usa cuando no sólo queremos saber si tienen el mismo valor, sino cuál es "mayor" o "menor".
Si hablamos de cadenas, "mayor" y "menor" se refieren a cuál va antes por órden alfabético.
Si sólo nos interesa saber si son iguales o distintas, usamos equals. Si necesitamos saber cuál es menor o mayor, usamos compareTo.