Collection contains

7 respostas
danielbchaves

Possuo duas coleções e preciso saber se uma delas contém pelo menos um elemento da outra

vi q o contains retorna true apenas se a coleção contiver toda a outra coleção

até agora fiz um loop em uma delas e usei o contains para cada um dos itens

tem alguma forma melhor de fazer isso, algum jeito de fazer sem um for?

7 Respostas

sergiotaborda

danielbchaves:
Possuo duas coleções e preciso saber se uma delas contém pelo menos um elemento da outra

vi q o contains retorna true apenas se a coleção contiver toda a outra coleção

até agora fiz um loop em uma delas e usei o contains para cada um dos itens

tem alguma forma melhor de fazer isso, algum jeito de fazer sem um for?

Se as coleções A e B não têm elementos em comum elas são dijustas.
Se elas têm pelo menos 1 elementos em comum elas não são dijuntas.

Para testar de elas têm pelos menos um elemento basta testar de são dijuntas.
Use o Collections.dijoint() ( exisge Java 1.5 ou superior)

boolean isDisjoint = Collections.disjoint(A,B);
danielbchaves

esqueci de comentar… precisa ser java 1.4 :?

ViniGodoy
Essa é a implementação do método disjoint:
public static boolean disjoint(Collection<?> c1, Collection<?> c2) {
        if ((c1 instanceof Set) && !(c2 instanceof Set) ||
            (c1.size() > c2.size())) {
            Collection<?> tmp = c1;
            c1 = c2;
            c2 = tmp;
        }

        for (Object e : c1)
            if (c2.contains(e))
                return false;
        return true;
    }
E

Ou seja, o método em questão é implementado da forma que o autor do tópico implementou…Pelo que entendi…

ViniGodoy

Só tem aquela otimização inicial ali.

Ele faz com que a coleção que tenha o contains seja um set (se possível).
E se não tiver como, faz com que ela seja a menor das duas.

ViniGodoy

Notei que tem um bug feio na otimização.

Se c1 for uma List e c2 um set. E c2 < c1 (o que seria a situação ideal), as coleções serão trocadas, e o método irá se comportar da maneira mais lenta possível.

A heurística ficaria melhor assim:
public static boolean disjoint(Collection&lt;?&gt; c1, Collection&lt;?&gt; c2) {
        if (!(c2 instanceof Set) && (c1 instanceof Set || c1.size() &gt; c2.size())) {
            Collection&lt;?&gt; tmp = c1;
            c1 = c2;
            c2 = tmp;
            System.out.println(&quot;Swapping collections.&quot;);
        }
        
        for (Object e : c1) {
            if (c2.contains(e)) {
                return false;
            }
        }
        
        return true;
    }

Isso garante que c1 e c2 só serão trocados se c2 não for um set.
Caso contrário, deve-se trocar as coleções se c1 for um set ou se c1 < c2.

Já abri um RFE na Sun a respeito disso.

danielbchaves

vlw gente, isso deve ajudar mesmo… gostei desse lance de otimização antes do for

Criado 19 de julho de 2008
Ultima resposta 21 de jul. de 2008
Respostas 7
Participantes 4