Ordenando Strings

6 respostas
Fellipex

Seguinte galera, to fazendo um trabalho da faculdade e o professor pediu para criarmos um programa que recebe uma lista de filmes que possuem os seguinte atributos
-Nome do filme
-Nome do diretor
-Ano de lancamento
-Nome da produtora

E para cada atributo desse o usuario pode informar se quer na ordem crescente ou decrescente , entretanto o usuario pode informar apenas um desses atributos(nome do filme, nome do diretor, etc) ou informar varios deles e caso por exemplo existam 2 filmes com o mesmo nome, entao esses 2 eu tenho que ordenar pelo proximo filtro de ordem como por exemplo nome do diretor, etc. Porém já tentei varias maneiras de pensar num algoritmo que não me obrigue a eu fazer 1 IF para cada probabilidade de ordenamento.
Existe alguma maneira de eu construir o o ordenamento sem deixar fixo no código todas as probabilidades possiveis?
Vamos supor que o usuario digite
Nome do Filme - Ordem Crescente
Nome do Diretor - Ordem Decrescente

Eu não queria ter um if assim

if(primeiraOrdem.equals("Nome do Filme") && ordem.equals("Ordem Crescente")){
        //percorra a lista
        //faça comparacao por nome do Filme e ordena em ordem Crescente
       //se existir 2 nomes iguais soma 1 a algum contador para ordenar por outra ordenação
       if(contador > 0 ){
          if(SegundaOrdem.equals("Nome do Diretor") && ordem.equals("Ordem Crescente"))
            // entao ordene por isso
          }else if(segundaOrdem.equals("Nome do Diretor") && ordem.Equals("Ordem Decrescente")){
           // senao ordena por isso
         if(SegundaOrdem.equals("Ano de Lancamento") && ordem.equals("Ordem Crescete")){
          // ou por isso 
         // e por ai vai
       }
}

Vocês entenderam meu problema? Isso é 1 entra varias possibilidades e não estou conseguindo pensar numa forma Genérica na qual voce diz que quer ordenar Primeiro por tal campo e ordem ascendente ou descendente, depois caso em algum momento dessa ordenacao existir registros com mesmo nome , entao ordene pelo segundo campo definido e por ai vai. Porém como eu disse o usuario pode informar que o primeiro campo é tal e o ordenamento é ascendente , que o segundo campo é tal e o ordenamento é descendente etc. Se alguém puder pelo menos me dar uma luz, ja seria de grande ajuda, pois estou fritando meus neurônios e não estou conseguindo produzir muita coisa. Desde já agradeço pela atenção. Valeu

6 Respostas

kcobainnn

Provavelmente os ifs você vai ter que fazer, só não vai precisar dessa forma que você fez que na verdade eu não entendi.
Você pode criar uma classe Comparator para cada tipo de ordenação, assim de acordo com o que o usuário digitar, você usar o comparator.

public void ordenar(EnumTipoOrdenacao tipo, List<Filme> filmes){
       if(tipo.equals(EnumTipoOrdenacao.DIRETOR_CRESCENTE)){
         Collections.sort(filmes, new DiretorCrescenteComparator());
       }

//...
}
Fellipex

Mas assim, vamos supor que o usuario digite que quer ordenar da seguinte forma

Diretor - Crescente
Filme - Decrescente

E em algum trecho do meu for que está rodando a lista de filmes, nesse momento encotnro 2 filmes que tem o mesmo diretor , logo nesse momento eu tenho que ordenar por filme, e depois continuar ordenando por Diretor. Porém da maneira que você disse quando eu faço if verificando se é DIRETOR_CRESC e dou um collections.sort eu estou ordenando apenas por diretor, não tem como eu incluir nessa ordenacao para quando algum registro tenha valores iguais para o mesmo filtro, eu ordenar pelo proximo filtro escolhido certo? Você teria algum exemplo do que eu falei? Tipo ordenação por mais de um filtro para ordenar pelo proximo filtro quando existam registros com mesmos valores

Tipo como seria a implementação disso

Diretor - Crescente
Filme - Decrescente

Para os seguintes filmes

João - FilmeA
João - FilmeB
André - FilmeC

Nesse caso tenho 2 diretores com o mesmo nome, então para resolver esse caso existiria alguma maneira genérica? Ja pensei de tudo, mas a unica coisa que me vem a cabeça é fazer um If para cada probabilidade possível. Valeu

di.magdaleno

Fellipex:
Mas assim, vamos supor que o usuario digite que quer ordenar da seguinte forma

Diretor - Crescente
Filme - Decrescente

E em algum trecho do meu for que está rodando a lista de filmes, nesse momento encotnro 2 filmes que tem o mesmo diretor , logo nesse momento eu tenho que ordenar por filme, e depois continuar ordenando por Diretor. Porém da maneira que você disse quando eu faço if verificando se é DIRETOR_CRESC e dou um collections.sort eu estou ordenando apenas por diretor, não tem como eu incluir nessa ordenacao para quando algum registro tenha valores iguais para o mesmo filtro, eu ordenar pelo proximo filtro escolhido certo? Você teria algum exemplo do que eu falei? Tipo ordenação por mais de um filtro para ordenar pelo proximo filtro quando existam registros com mesmos valores

Tipo como seria a implementação disso

Diretor - Crescente
Filme - Decrescente

Para os seguintes filmes

João - FilmeA
João - FilmeB
André - FilmeC

Nesse caso tenho 2 diretores com o mesmo nome, então para resolver esse caso existiria alguma maneira genérica? Ja pensei de tudo, mas a unica coisa que me vem a cabeça é fazer um If para cada probabilidade possível. Valeu


Crie duas classes que implementem Comparator uma que ordene pelo nome do filme e outra que ordene pelo nome do diretor.

Por exemplo, caso queira ordenar pelo nome do filme e, como segundo critério, pelo nome do diretor, primeiro ordene a lista pelo nome do diretor e depois pelo nome do filme. Dessa forma a lista já estará ordenada pelo nome do diretor quando ordenar pelo nome do filme.

Mais ou menos assim:

Collections.sort(filmes, new PorDiretorComparator()); //Ordena a lista pelo nome do diretor Collections.sort(filmes, new PorFilmeComparator()); //Ordena a lista pelo nome do filmeComo já estava ordenada pelo nome do diretor ao ordenar pelo nome do filme, o atributo nome do diretor fica como segundo critério na ordenação. A mesma lógica funciona caso queira ordenar um dos dois inversamente.

Fellipex

Eu posso estar fazendo confusão, mas neste caso se eu fizer 2 collections .sort o ultimo Collections que ordenará a lista. Mas na verdade eu só queria que ordenasse pelo proximo filtro os registros que tem o mesmo valor pelo ordenacao inicial

Tipo

Joao - FilmeA
Joao - FilmeB
Maria - FilmeC
Andre - FilmeD
Felipe - FilmeC

Se eu solicitar
ordene

Diretor crescente
Livro decrescente

Teria que ficar assim

Andre - FilmeD
Felipe - FilmeC
Joao - FilmeB
Joao - FilmeA
Maria - FilmeC

Se eu fizer um Collections.sort , ordenando primeiro pelo nome do diretor logo em seguida eu ordenar pelo nome do filme vai ficar assim não?

Nome do diretor

Andre - FilmeD
Felipe - FilmeC
Joao -FilmeA
Joao- FilmeB
Maria - FilmeC

E agora pelo nome do filme

Joao - FilmeA
Joao- FilmeB
Fellipe-FilmeC
Maria-FilmeC
Andre-FilmeD

Eu entendi que ficaria assim, mas tipo não é isso que eu gostaria, eu queria que a ordenacao utilizando o proximo filtro informado, só ordenasse os registros que na ordenacao anterior possuiam valores iguais. Estou correto na minha duvida?

di.magdaleno

Olha, não sei se compreendi muito bem o que você quis dizer então. O que eu entendi foi:

Considerando a Lista Inicial abaixo:
Diretor 1 - Filme 1
Diretor 2 - Filme 2
Diretor 3 - Filme 3
Diretor 1 - Filme 3
Diretor 1 - Filme 2
Diretor 3 - Filme 1

Lista inicial ordenada por Diretor:
Diretor 1 - Filme 1
Diretor 1 - Filme 3
Diretor 1 - Filme 2
Diretor 2 - Filme 2
Diretor 3 - Filme 3
Diretor 3 - Filme 1

  • Repare que nesse exemplo a lista de filmes está desordenada para o Diretor 1 e para o Diretor 3

Lista inicial ordenada por Filme:
Diretor 1 - Filme 1
Diretor 3 - Filme 1
Diretor 2 - Filme 2
Diretor 1 - Filme 2
Diretor 3 - Filme 3
Diretor 1 - Filme 3

Lista primeiramente ordenada por Filme e depois por Diretor:
Diretor 1 - Filme 1
Diretor 1 - Filme 2
Diretor 1 - Filme 3
Diretor 2 - Filme 2
Diretor 3 - Filme 1
Diretor 3 - Filme 3

  • Repare que dessa forma a lista de filmes do Diretor 1 e do Diretor 3 são ordenadas entre si. O Diretor 2 não é alterado nesse caso porque ele possui apenas um filme.

A ordenação final da lista vai ser dada pelo último Collections.sort() que você fizer, isso é fato. Mas, quando você faz um sort numa lista já ordenada a ordenação é feita baseada na ordem anterior. Ou seja, no exemplo acima, quando a lista inicial é ordenada por Diretor ela fica ordenada por diretor e os Filmes ficam na ordem da lista inicial. Ao realizar primeiramente a ordenação pelo nome do filme, a ordenação por Diretor é feita com base em uma lista já ordenada por filme e essa ordem é mantida durante o processo.

Compare os exemplos acima, vai ficar mais fácil de compreender o que eu quero dizer.

kcobainnn

Deixa eu ver se eu entendi, você precisa ordernar com mais de um critério, certo?

Não tem mistério, exemplo

public int compare(Filme f1, Filme f2){
      if(f1.getNome().compareTo(f2.getNome()) != 0){
            return f1.getNome().compareTo(f2.getNome());
      }

      if(f1.getDiretor().compareTo(f2.getDiretor()) != 0) {             
            return f1.getDiretor().compareTo(f2.getDiretor());      
      }

       //...
}

Dessa forma você usa mais de um critério de avaliação p/ comparar, estaria falando mais ou menos assim: “Caso os nomes forem iguais, não faça nada e ordene pelo diretor”, e assim vai…

Criado 8 de abril de 2013
Ultima resposta 8 de abr. de 2013
Respostas 6
Participantes 3