2
respostas

Desafio Collections

Esse post contêm duvidas sobre o método shuffle e como poderia criar um método próprio de embaralhamento e também contêm minha conclusão sobre o desafio.

1º Método reverse:

Collections.reverse(lista);

2º Método shuffle:

Collections.shuffle(lista);

Sobre o método shuffle como eu poderia definir um critério de embaralhamento? Já tentei fazer como o método/interface Comparator e não obtive sucesso.

3º Método rotate:

Collections.rotate(lista, pos);

Sobre esse método fiz algumas observações e gostaria de confirmar se estou certo.

1º Quando se utiliza números positivos na posição a contagem começa do ultimo elemento para o primeiro, invertendo assim a ordem de saída de todos os elementos subsequentes. EXEMPLO:

Entrada:

List<Conta> lista = new ArrayList<>();
        lista.add(cc1);
        lista.add(cc2);
        lista.add(cc3);
        lista.add(cc4);
        lista.add(cc5);
for (Conta conta : lista) {
            System.out.println(conta + ", "  + conta.getTitular().getNome());
        }

Saída:

cc1
cc2
cc3
cc4
cc5

Entrada:

// Repetindo o código da primeira entrada
Collections.rotate(lista, 2);

Saída:

cc4 // O 2º elemento contando a partir do ultimo
cc5
cc1
cc2
cc3

2º Caso o número utilizado no lugar do pos seja negativo, o efeito é contrário, começando a contagem do primeiro elemento(0, o 0 é o mesmo que a lista padrão) e assim por diante. EXEMPLO:

Entrada:

// Mesma entrada do primeiro exemplo
Collections.rotate(lista, -2);

Saída:

cc2
cc3
cc4
cc5
cc1

A postagem ficou um tanto extensa, mas espero que tenha sido clara.

Resumindo, gostaria de saber como criar meu método de embaralhamento e se as conclusões que tirei sobre o método rotate estão corretas.

Obrigado :)

2 respostas

Ainda sem respostas :?

Olá Raphael, tudo bem com você? Peço perdão pela demora no retorno!

No caso do Collections.shuffle(), realmente não tem como criar um critério de embaralhamento, já que o propósito do método é reorganizar uma lista de forma randômica. Ou seja, a partir do momento em que queremos impor condições no embaralhamento, estamos lidando com uma situação onde estamos ordenando a lista através de um critério de comparação.

Em relação ao Collections.rotate(), ele começa a rotacionar a partir do primeiro elemento. Veja como é feita a implementação por baixo dos panos:

private static <T> void rotate1(List<T> list, int distance) {
    int size = list.size();
    if (size == 0)
        return;
    distance = distance % size;
    if (distance < 0)
        distance += size;
    if (distance == 0)
        return;

    for (int cycleStart = 0, nMoved = 0; nMoved != size; cycleStart++) {
        T displaced = list.get(cycleStart);
        int i = cycleStart;
        do {
            i += distance;
            if (i >= size)
                i -= size;
            displaced = list.set(i, displaced);
            nMoved ++;
        } while (i != cycleStart);
    }
}

Assumindo que a distancia (ou posição) que passamos ao método rotate() seja positiva, o método irá varrer a lista enquanto desloca os elementos para as casas seguintes de acordo com a distancia que definimos, isso ao mesmo tempo em que vai armazendo os elementos que foram substituídos numa variável chamada displaced para que na próxima iteração ela seja atribuída a uma próxima posição.

Como você pode ver, não é um algoritmo tão simples de entender à primeira vista, então pode ser interessante usar a ferramenta de debug que as IDEs oferecem afim de ver o passo a passo com calma.

No final das contas, o que você vai acabar criando é um método de ordenação e não embaralhamento, você pode até colocar várias condições aleatórias na hora de ordenar para ficar difícil de encontrar um padrão, mas no final ainda será um método de ordenação por baixo dos panos.

Fez sentido? Se ficou alguma dúvida, por favor, me avise!

Forte abraço e bons estudos!! ;)