[ Resolvido ] Ordenação de ArrayList

12 respostas
J

Boa noite,

Gostaria de um auxílio para iniciar um trabalho de aula, tenho um arrayList de filmes, com atributos (nome, nota, gênero, nº de votos, ano lançamento, diretor…) Preciso ordenar este arrayList por nota por exemplo, se tiver dois com notas iguais o desempate é quantidade de votos. Tentei uma solução que encontrei aqui forum, que era Collections.sort(nome do meu arrayList), mas não funcionou, mesmo importando java.util.*… Na verdade não sei o comando pra isso, procurei na API mas ainda acho meio confuso… pesquisei por arrayList e li tudo, mas mais me atrapalhei que tirei minha dúvida…

Tenho por exemplo declarado meu arrayList de filmes assim:

private ArrayList<Filme> lista;

depois preciso que esta lista seja ordenada por um atributo do filme…

Grato,

12 Respostas

Filipe_A

Ola,

Eu acho que você deve implementar uma a interface Comparator.

tem um exemplo aqui tirado do Head First Java

public class Song implements Comparable<Song> {

	// Four instance variables for the four song attributes in the file.
	String title;

	String artist;

	String rating;

	String bpm;

	// The variable are all set in the constructor when the new Song is created.
	public Song(String t, String a, String r, String b) {
		title = t;
		artist = a;
		rating = r;
		bpm = b;
	}

	// The HashSet(or anyane else calling this method)sends it to another song
	@Override
	public boolean equals(Object aSong) {
		Song s = (Song) aSong;
		// The GREAT news is that title is a String, and Strings have an
		// overrride equals() method. So all we have to do is ask one title is
		// it's equal to the other song's title.
		return getTitle().equals(s.getTitle());
	}

	@Override
	public int hashCode() {

		// Same deal here ... the String class has an overriden hashCode()
		// method, so you can just return the result of calling hashCode on the
		// title. Notice how hashCode and equals() are using the SAME instance
		// variable.
		return title.hashCode();
	}

	// T he getter methods for the four atributes.
	public String getArtist() {
		return artist;
	}

	public String getBpm() {
		return bpm;
	}

	public String getRating() {
		return rating;
	}

	public String getTitle() {
		return title;
	}

	// We override toString(), because when you do a
	// System.out.println(aSongObject) , we want to see the title. When you do a
	// syso(aListOfSongs), its calls the toString() methoid of EACH element in
	// the list.
	@Override
	public String toString() {
		return title;
	}

	public int compareTo(Song s) {
		return title.compareTo(s.getTitle());
	}

}
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

public class JunkeBox {

	ArrayList<Song> songList = new ArrayList<Song>();

	public static void main(String[] args) {
		new JunkeBox().go();
	}

	class ArtistCompare implements Comparator<Song> {

		public int compare(Song one, Song two) {

			return one.getArtist().compareTo(two.getArtist());
		}
	}

	void go() {

		getSongs();
		System.out.println(songList);
		Collections.sort(songList);
		System.out.println(songList);

		ArtistCompare artistCompare = new ArtistCompare();
		Collections.sort(songList, artistCompare);
		
		System.out.println(songList);
	}

	void getSongs() {
		try {
			File file = new File("SongListMore.txt");
			BufferedReader reader = new BufferedReader(new FileReader(file));
			String line = null;
			while ((line = reader.readLine()) != null) {
				addSong(line);
			}
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}

	void addSong(String lineToParse) {
		String[] tokens = lineToParse.split("/");

		Song nextSong = new Song(tokens[0], tokens[1], tokens[2], tokens[3]);
		songList.add(nextSong);
	}

}

Ve se te ajuda em algo. :slight_smile:

J

Obrigado pela dica, mas não me adiantou muito, acho que porque ainda estou aprendendo e conheço pouco, o que gostaria de saber é se tem um método para ordenar um arrayList(que eu ja tenho) por um atributo qualquer. Se possível com exemplo, pois tentei usar Collections.sort, mas acho que este método não é pra arrayList, pois não funcionou…

Ou se tem alguma maneira mais fácil para fazer isto, pois ja recebi o trabalho parcialmente implementado, restando fazer várias pesquisas e ordenações e mostrar as saidas(menu com todas as opções solicitadas…).

Grato,

ViniGodoy

É o Collections.sort. Mas para ele funcionar, precisa implementar o Comparator, como o colega falou. Dá uma lida aqui:
http://www.guj.com.br/posts/list/54036.java#284273

cristian_clever

Bom dia amigo!

Aqui tbm:
http://www.guj.com.br/posts/list/138572.java

[]s

J

Grato pessoal,

Mas eu achei meio complicado tentar implementar este Comparator agora, pois to aprendendo o básico ainda(primeira cadeira de Algorítmos e programação O.O), não por falta de interesse, mas porque estou no fim do semestre e tenho mais trabalhos e provas pra me dedicar, semestre que vem vou começar a me aprofundar mais em AlproII(algoritmos e programação II), por enquando é o básico mesmo, achei melhor e mais rápido fazer do método mais fácil(embora bem pouco eficiente), usando o método set do Arraylist passando a posição … com o velho Bubble Sort.
dai pra mim ordenar meu arrayList de filmes por notas e com desempate por votos ficou assim:

// ordena filmes por nota,desempate por votos.
    public void ordenaPorNota() {
        Filme a = null, b=null;
        boolean ordenado = false;
        
        while(ordenado == false){
            ordenado = true;
            for (int pos=0; pos < lista.size();pos++){
              if (pos+1 < lista.size()){
                  a = lista.get(pos);          // lista é o Arraylist de Filmes
                  b= lista.get(pos+1);
                  if(a.getNota() < b.getNota()){
                      ordenado = false;
                      lista.set(pos,b);
                      lista.set(pos+1,a);
                    }
                    else if (a.getNota() == b.getNota()) {
                        if (a.getVotos() < b.getVotos()) {
                             ordenado = false;
                             lista.set(pos,b);
                             lista.set(pos+1,a);
                        }
                    }
                }
             }
        }
    }

Foi a primeira tentativa e funcionou, mas deve dar pra otimizar mais… Acho que poderia ter posto o for indo só até list.size()-1… mas assim ta legal já.

Agora se puderem me tirar mais uma dúvida, que é do mesmo trabalho, mas não sei se precisa criar outro tópico.

É o seguinte: preciso listar todos os filmes de um ator… A princípio é só criar um método que retorna uma String e percorrer o arrayList de filmes e ir comparando o nome de um ator passado por parâmetro no método com o atributo do filme “ator”, só que o ator ta dentro de outro arrayList do tipo Personagens (que guarda nome do astro e o nome do ator) .

A questão e: Como chegar neste ator para comparar com a ator que passo por parâmetro… To meio confuso, pois se quando instancio um arraylist de filmes ja é pra vir dentro o array de personagem…Então tentei acessar assim: OBS. O método abaixo esta incompleto porque vi que a pesquisa não ta funcionando…

public String listaFilmesDeUmAtor(String ator) {
        String list = "";
        
         for (int pos = 0; pos < lista.size();pos++){
             if (lista.get(pos).getElenco().getNome().equalsIgnoreCase(ator)) {  // elenco é o arrayList de Personagens...
                   list += lista.get(pos).toString();
             }
         }

Grato,
Jeferson Neves

J

Grato pessoal, mas ja resolvi o problema… Na verdade não sei se é a melhor alternativa, mas criei um um método boolean que vai filme a filme percorrendo o arrayList de atores(atributo do filme) e retorna true se ele estiver no arrayList… com isso eu sei se ele faz parte do elenco do filme e como o que quero fazer é com o filme e só interessa saber se o ator faz parte ou não do elenco ja ta ok pra o que quero…

Grato,

sergiotaborda

jefers0n:
Grato pessoal,

Mas eu achei meio complicado tentar implementar este Comparator agora, pois to aprendendo o básico ainda(primeira cadeira de Algorítmos e programação O.O), não por falta de interesse, mas porque estou no fim do semestre e tenho mais trabalhos e provas pra me dedicar,

Esse desculpa quase que colou. mas quando vc escreve um monte de codigo que podia ser substituido por 5 linhas… vc perde todo o credito. Implemente Comparator e deixe-se de desculpas.

Collections.sort(arrayList, new Comparator<Filme>(){
 public int compare(Filme a, Filme b){
         return a.getNota() > b.getNota() ? 1 :
                   ( a.getNota() < b.getNota() ? -1 : 0);                    
} 
});
ViniGodoy

Concordo com o sergio. Usando ainda seu critério de desempate:

public void ordenaPorNota() {  
   Collections.sort(lista, new Comparator<Filme>() {
      public int compare(Filme o1, Filme o2) {
         int nota = o2.getNota() - o1.getNota();
         return nota != 0 ? nota :  o2.getVotos() - o1.getVotos();
      });
}

Note que a comparação está invertida entre o1 e o2, já que você quer ordenar da maior para a menor nota.

MarcioCasteloBranco

Vamos lá aprenada pelo metodo correto use o comparador serão 2 horas de estudo que não terão preço!

J
sergiotaborda:
jefers0n:
Grato pessoal,

Mas eu achei meio complicado tentar implementar este Comparator agora, pois to aprendendo o básico ainda(primeira cadeira de Algorítmos e programação O.O), não por falta de interesse, mas porque estou no fim do semestre e tenho mais trabalhos e provas pra me dedicar,

Esse desculpa quase que colou. mas quando vc escreve um monte de codigo que podia ser substituido por 5 linhas... vc perde todo o credito. Implemente Comparator e deixe-se de desculpas.

Collections.sort(arrayList, new Comparator<Filme>(){
 public int compare(Filme a, Filme b){
         return a.getNota() > b.getNota() ? 1 :
                   ( a.getNota() < b.getNota() ? -1 : 0);                    
} 
});

Concordo também que eu poderia deixar de fazer uma coisa menos eficiente e maior para tentar aprender algo mais eficiente e que no "mundo real" seria o que teria de usar, mas minha própria profª ensinou, por enquanto, ordenar assim (com bubble sort) e informou que não é muito eficiente e que existem meios menores e muito melhores para se fazer isto, mas que aprenderemos no semestre que vem... Mesmo com tudo isso eu poderia me dedicar (extra-aula) e aprender coisas novas, mas falta praticamente 1 mês pra finalizar o semestre e pretendo não ficar em G2 em nenhuma das cadeiras(por exemplo semana que vem tenho 3 provas e um trabalho de cálculo, que pra mim é a cadeira mais difícil), e "mais desculpas"além disso tenho filhos, problemas particulares, casa para administrar, dentro outras coisas que tomam muito tempo e que com certeza, se eu parar para me dedicar muito mais em uma cadeira, deixarei a desejar em outra, pois mal estou tendo tempo pra manter-me na média em tudo e conciliar o resto(que é bastante coisa...).

Sei que são mais desculpas, mas realmente to sem tempo e não posso vacilar no final do semestre... Sei também que esta é a realidade de muitos, mas estou tentando levar as coisas da melhor maneira possível, balanceando o tempo/dedicação para todos os problemas...

Grato a todos,

MarcioCasteloBranco

Eu te entendo e te compreendo tenho filho curso Ciência da computação sou casado, to cheio de dividas, fica tranquilo mas nunca perca este espirito de curiosidade, e força cara a única certeza que tenho é uma hora o buraco vai ter fim, e enquanto estou na queda já estou pensado como vou sair, cara a minha é mais uma historia de um filho de Deus, que só tem a ELE, e a família, e minha capacidade na vida!!!
Não quero remorso, e nem pena de ninguém, pois enquanto o sangue estiver quente na minha veia, eu não desisto, este é meu jeito ninja de ser !!
Obrigado!!!

J

MarcioCasteloBranco:
Eu te entendo e te compreendo tenho filho curso Ciência da computação sou casado, to cheio de dividas, fica tranquilo mas nunca perca este espirito de curiosidade, e força cara a única certeza que tenho é uma hora o buraco vai ter fim, e enquanto estou na queda já estou pensado como vou sair, cara a minha é mais uma historia de um filho de Deus, que só tem a ELE, e a família, e minha capacidade na vida!!!
Não quero remorso, e nem pena de ninguém, pois enquanto o sangue estiver quente na minha veia, eu não desisto, este é meu jeito ninja de ser !!
Obrigado!!!

Cara é isso aí…

Concordo com vc, grande abraço e fica com Deus.

Obrigado a todos e acho que este tópico ja pode ficar como resolvido, pois ja consegui o que queria e ja sei também uma maneira melhor de fazer o que queria saber, que estarei estudando em breve. mais uma vez muito obrigado a todos.

Criado 18 de novembro de 2009
Ultima resposta 26 de nov. de 2009
Respostas 12
Participantes 6