Pergunta

public final Comparator<String> ID_IGN_CASE_COMP = new Comparator<String>() {

        public int compare(String s1, String s2) {
            return s1.compareToIgnoreCase(s2);
        }
    };

private Map< String, Animal > _animals = new TreeMap< String, Animal >(ID_IGN_CASE_COMP);

Meu problema é que o método de usar (id) ignorando o comparador fornecido. Quero que o mapa seja ordenado por caso insensível, mas quero que seja sensível ao caso quando busco os valores por uma determinada chave.

Foi útil?

Solução

Eu acho que a resposta é fácil. Implemente seu próprio comparador que faz um tipo de caso insensível, mas NÃO Retorne 0 para "A" e "A" ... classifique -os também.

A questão é que seu comparador retorna 0 para o caso Compare ("A", "A" A "), o que significa que é a mesma chave no que diz respeito ao mapa.

Use um comparador como:

public final Comparator<String> ID_IGN_CASE_COMP = new Comparator<String>() {

    public int compare(String s1, String s2) {
        int result = s1.compareToIgnoreCase(s2);
        if( result == 0 )
            result = s1.compareTo(s2);
        return result;
    }
};

Em seguida, todas as chaves serão exibidas independentemente do caso e "A" e "A" ainda serão classificadas juntas.

Em outras palavras, Get ("A") lhe dará um valor diferente de get ("a") ... e ambos aparecerão no Keyset () iteradores. Eles serão classificados juntos.

Outras dicas

Em um TreeMap, adicionar duas teclas A e B (nessa ordem) para que compare (a, b) retorna 0 resultará em que a entrada mais recente adicionada (b) substitua a primeira (a).

No seu caso, isso significa que nunca haverá uso para get insensível de caso (id).

citando http://java.sun.com/javase/6/docs/api/java/util/treemap.html

Observe que a ordem mantida por um mapa classificado (seja ou não um comparador explícito) deve ou não ser consistente com iguais se esse mapa classificado for implementar corretamente a interface do mapa. (Veja comparável ou comparador para obter uma definição precisa de consistente com iguais.) Isso ocorre porque a interface do mapa é definida em termos da operação igual, mas um mapa executa todas as comparações principais usando seu método compareto (ou compare), portanto, duas teclas que são considerados iguais por esse método são, do ponto de vista do mapa classificado, igual. O comportamento de um mapa classificado é bem definido, mesmo que sua ordem seja inconsistente com iguais; Ele não consegue obedecer ao contrato geral da interface do mapa.

Provavelmente não é isso que você deseja.

Se o mapa for comparativamente pequeno e você não precisar buscar as entradas classificadas muitas vezes, uma solução é usar um hashmap (ou um Treemap sem definir explicitamente o comparador) e classificar as entradas insensíveis quando você precisar delas ordenado.

Você terá que usar dois mapas mais separados para isso, com o mesmo conteúdo, mas comparadores diferentes.

Talvez isso faça o trabalho:

    new Comparator<String>(){
    public int compare(String s1, String s2)
    {
        String s1n = s1.toLowerCase();
        String s2n = s2.toLowerCase();

        if(s1n.equals(s2n))
        {
            return s1.compareTo(s2);
        }
        return s1n.compareTo(s2n);
    }
};
                                                    }

você precisa de um MultiMap: Cada entrada deste multimap mantém o Case insensível chaves e outros mapas com as teclas originais como valor.

Existem muitas implementações gratuitas de multimaps, como Coleções comuns, Coleções do Google, etc.

Além de todas as outras respostas e concordamento, é impossível ter uma única estrutura Treemap com diferentes comparadores:

Pela sua pergunta, entendo que você tem dois requisitos: o modelo de dados deve ser sensível ao caso (você deseja os valores sensíveis ao caso quando usar get()), o apresentador deve ser insensível ao caso (você deseja uma ordem sensível ao caso, a apresentação é apenas uma suposição).

Vamos supor, preenchemos o mapa com os mapeamentos (aa, obj1), (aa, obj2), (aa, obj3), (aa, obj4). O iterador fornecerá os valores na ordem: (obj4, obj3, obj2, obj1) (*). Agora, qual pedido você espera se o mapa foi encomendado de entrega de caso? Todas as quatro chaves seriam iguais e a ordem indefinida. Ou você está procurando uma solução que resolvesse a coleção {obj1, obj2, obj3, obj4} para a chave 'aa'? Mas essa é uma abordagem diferente.

Portanto, incentiva a comunidade a ser honesta: portanto, meu conselho neste momento é olhar para a sua exigência novamente :)

(*) não testado, assumiu que 'a' <'a' = true.

Usar FloorEntry e depois superior em um loop para encontrar as entradas e desensibilizadas; Pare quando encontrar a correspondência de chave exata.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top