Why do we have equals() and equalsIgnoreCase() as two different methods, when equals() could have been overloaded with a special
Because equals() method is inherited from Object.
If they did it as you suggest then we would have something like this:
public final class String {
public boolean equals () { ... }
public boolean equals (boolean ignoreCase) { ... }
}
And without reading documentation it would be impossible to understand what method equals() (which without parameter) do.