A razão é que o contrato desses métodos é aberto. O contrato especifica que para que esses métodos retornem true (ou um valor do mapa, no caso do get), eles precisam de um objeto que passe no teste do equals e não sejam nulos. Não dizem que precisam ser exatamente do mesmo tipo da chave.
Isso permite, por exemplo, que objetos proxies sejam usados como valores no get. Vamos supor que você tenha um proxy (ClienteReadOnly) que seja simplesmente uma versão imutável de um outro objeto da sua aplicação (digamos, da classe Cliente), mutável. E esse proxy foi usado como chave do seu map. Você poderia usar o equals para testar contra objetos do tipo cliente.
Outra opção seria testar se um List está entre os valores do map, mesmo que seja um list de uma implementação diferente da que esteja num map. Por exemplo, dentro do map vc ter um linkedList, mas quer saber num containsValue se existe uma lista com os mesmos elementos de um ArrayList.
Agora, eu concordo com você. Eu também faria esses métodos com o tipo correspondente. Acho que o benefício de se ter verificação em compile time é muito maior do que o benefício do recurso que citei acima, principalmente porque o equals geralmente retorna false quando usado com tipos diferentes, e também porque quando é o caso de retornar true, ele geralmente vai ser com uma classe que implementa uma superclasse ou interface comum (caso da List).