O método IndexOf retorna 0 quando deveria retornar -1 em C#/Java
Pergunta
Um amigo meu veio até mim com esse comportamento estranho que não consigo explicar, qualquer visão esclarecedora seria apreciada.
Estou executando o VS 2005 (C# 2.0), o código a seguir mostra o comportamento
int rr = "test".IndexOf("");
Console.WriteLine(rr.ToString());
o código acima, imprima "0", que mostra claramente que deveria retornar -1
Isso também acontece em Java onde a seguinte classe mostra o comportamento:
public class Test{
public static void main(String[] args){
System.out.println("Result->"+("test".indexOf("")));
}
}
Estou executando Java 1.6.0_17
Solução
Isso não é uma exceção à regra, mas uma consequência natural de como indexOf
e startsWith
são definidos.
Você está reivindicando isso "test".indexOf("")
deve voltar -1
. Isso é essencialmente equivalente à alegação de que "test".startsWith("")
deve voltar false
. Por que é isso? Embora este caso seja abordado especificamente na documentação como retornando true
, Esta não é apenas uma decisão arbitrária.
Como você decidiria "test".startsWith("te")
, por exemplo? A maneira mais simples é usar a recursão. Desde que ambas as cordas começam com o personagem 't'
, você chama "est".startsWith("e")
e devolver o resultado. Da mesma forma, você vai ligar "st".startsWith("")
e devolver o resultado. Mas você já sabe que a resposta deve ser true
, é por isso que toda string começa com ""
.
Outras dicas
Citação do C# documentação:
Se o valor for Vazio, o valor de retorno é 0.
O comportamento que você descreve é inteiramente esperado (pelo menos em C#).
0 está correto. Comece na posição zero e você posso (trivialmente) corresponde a uma corda de comprimento zero. Da mesma maneira, "" contém "".
0 está correto. Os javadocs apontam que indexOf
funciona da seguinte maneira:
O número inteiro retornado é o menor valor k de modo que:
this.startsWith(str, k)
Qualquer string começando com ""
é igual à string original (e toda string começa com ""
), então o menor k
por str = ""
é sempre 0.
Pense desta maneira: Indexof, ao procurar uma string, começará na posição 0, tente combinar com a string, se não se encaixar, vá para a posição 1, 2, etc. Quando você ligar com um vazio String, ele tenta corresponder à sequência vazia com a string iniciando na posição 0 com o comprimento 0. e Hooray, nada é igual a nada.
Nota lateral: não há motivo real para usar ToString
Quando você está usando o console.write/writeline. A função chama automaticamente o ToString
Método do objeto em questão. (A menos que sobrecarregar a tostragem)
Ele deve retornar 0. Você está procurando a primeira ocorrência de uma corda vazia, certo? :)
Mais PHP divertido realmente faz um trabalho muito melhor!
php -r "print strpos('test','');"
PHP Warning: strpos(): Empty delimiter. in Command line code on line 1
Apenas pela diversão disso. Também funciona assim em python
>>> "test".startswith("")
True
>>> "test".index("")
0
Python lança um ValueError em vez do -1 que é bom.
>>> "test".index('r')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: substring not found