Ordenação em Java

Oie gentem!! :slight_smile:

Estou tentando arrumar esse programa que tenho que entregar até a meia-noite de hoje no site que a minha facul mandou, esse programa comentado, mas falta ordenar os dados, mas eu não sei como posso fazer isso.

Eis abaixo a descrição do problema:


1 Descri¸c˜ao do problema
Um campeonato de futebol foi disputado por n times identificados pelos seus
nomes. Para cada time s˜ao considerados os seguintes dados:
PontosGanhos – n´umero de pontos ganhos (3 por vit´oria, 1 por empate, 0
por derrota);
GolsMarcados – n´umero de gols marcados;
GolsSofridos – n´umero de gols sofridos (gols dif´ıceis de marcar :) );
SaldoDeGols – saldo de gols (GolsMarcados - GolsSofridos);
Vitorias – n´umero de vit´orias;
GolAverage – gol average (GolsMarcados / GolsSofridos, cuidado se Gols-
Sofridos = 0).
Escreva uma classe CampeonatoFutebol que possua os seguintes m´etodos:
1. Dados os resultados de m jogos, que podem ser entrados pelo teclado,
gere uma tabela com os resultados dos jogos. Cada resultado ´e representado
na forma (t1,t2,n1,n2) cuja interpreta¸c˜ao ´e a seguinte: no jogo
t1 × t2 o resultado foi n1 × n2.
Exemplo: (S˜ao Paulo, Milan, 3, 2) que foi o placar da vit´oria que
deu ao S˜ao Paulo o BICAMPEONATO MUNDIAL (exemplo inclu´ıdo,
infelizmente, pelo prof. Jos´e :( ).
2. Com a tabela anterior gerar uma tabela com todos os dados (Pontos-
Ganhos, GolsMarcados, GolsSofridos, SaldoDeGols, Vitorias, Gol-
Average, igual `aquela que sai no jornal) dos n times.
1
3. Com os mesmos dados do item 2, gere e imprima a classifica¸c˜ao dos
times no campeonato (do primeiro para o ´ultimo). A classifica¸c˜ao ´e
pelo n´umero de pontos ganhos (PontosGanhos) e em segundo lugar
pelo saldo de gols (SaldoDeGols). Se houver empate segundo os dois
crit´erios, classifique os times envolvidos como quiser.
4. Escreva um m´etodo que recebe como parˆametro o nome do time (uma
cadeia de caracteres) e retorna as informa¸c˜oes associadas a ele. Necessarimente
este m´etodo dever´a utilizar busca bin´aria.
5. N˜ao se esque¸ca de criar os testes para a classe CampeonatoFutebol e
tamb´em para as classes adicionais que vocˆe criar.
2 Programa Principal
Este exerc´ıcio-programa deve ser executado em linha de comando, ou seja,
a classe CampeonatoFutebol deve conter um m´etodo public static void
main(String [] args) que obt´em do teclado os dados dos times.
3 Seria¸c˜ao – parte extra
´E
poss´ıvel melhorar o programa um pouquinho mais. Por exemplo, voce
pode gravar o campeonato em um arquivo em disco e posteriormente lˆe-lo
deste arquivo. Se vocˆe implementar esta fun¸c˜ao adicional, o seu EP vale 12
(doze) pontos.
Para implementar isso, vocˆe deve utilizar um mecanismo poderoso da linguagem
Java chamado de seria¸c˜ao de objetos (object serialization). Atrav´es
deste mecanismo, ´e poss´ıvel transformar um objeto em uma s´erie de bytes,
armazenando-os em um arquivo. Posteriormente, ´e poss´ıvel desseriar o objeto,
ou seja, ler os bytes do arquivo e transform´a-los em objetos na mem´oria
do computador.
Como este processo ´e um pouco complicado, para facilitar vida de vocˆes,
criamos a classe SeriadorCampeonato o que est´a dispon´ıvel no arquivo
SeriadorCampeonato.java (n˜ao ´e preciso entender o c´odigo). Para utilizar
essa classe, copie o arquivo .java para o diret´orio onde est˜ao os seus
.java (e compile). O uso da classe ´e bem simples, ela cont´em apenas os dois
seguintes m´etodos.
/**
* Grava um objeto da classe ’CampeonatoFutebol’ num arquivo.
2
*
* Par^ametros:
* - meuCampeonato o ’CampeonatoFutebol’ que ser´a gravado
* no arquivo
* - nomeDoArquivo o nome do arquivo onde ser´a gravado o
* ’CampeonatoFutebol’
*/
void gravaCampeonato (CampeonatoFutebol meuCampeonato,
String nomeDoArquivo);
/**
* L^e um ’Campeonato’ de um arquivo.
*
* Par^ametros:
* - nomeDoArquivo o nome do arquivo de onde ser´a lido o
* ’CampeonatoFutebol’
* Valor de retorno: um objeto ’CampeonatoFutebol’ correspon-
* dente ao cat´alogo lido do arquivo
*/
CampeonatoFutebol carregaCampeonato (String nomeDoArquivo);
Veja a seguir um exemplo de uso, assumindo que a vari´avel campeonato
j´a armazena um objeto da classe CampeonatoFutebol.
> SeriadorCampeonato s = new SeriadorCampeonato();
> s.gravaCampeonato(campeonato, "campeonato.dat");
> Campeonato campeonato2 = s.carregaCampeonato("campeonato.dat");
> campeonato2.imprimeClassificacao()
S´o um pequeno detalhe: antes de usar a classe SeriadorDeCampeonato ´e
necess´ario explicitar ao compilador Java que as classes do nosso campeonato
ser˜ao seriadas. Para isso, basta inserir o texto implements java.io.Serializable
depois do nome das classes. Assim, o seu c´odigo dever´a ser semelhante
ao seguinte:
3
class CampeonatoFutebol implements java.io.Serializable
{
// blabla...
}
Quaisquer classes extras criadas para implementar o catálogo também devem
conter esse texto. Por exemplo, se vocˆe criou uma classe auxiliar Xyz usada
pela classe CampeonatoFutebol, a declara¸c˜ao dela dever´a ser parecida com
a seguinte.
class Xyz implements java.io.Serializable
Depois disso, crie o m´etodo testaSeriacao na classe TestaCampeonato
que testa a seria¸c˜ao. Este m´etodo n˜ao precisa ser muito complicado, vocˆe
pode, por exemplo, usar os m´etodos j´a implementados da classe TestaCampeonato.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Bem é isso, ficou com um probleminha de formatação... heheheh, abaixo segue o programa, mas falta colocar a ordenação, e ainda não sei como fazer...  :cry: 

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[code]
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.List;
import java.util.Vector;

import javax.swing.JOptionPane;

/**
 * Cria exception caso o formato do comando seja errado
 *
 */
class FutebolException extends Exception{
 private static final long serialVersionUID = 1L;
 
 public FutebolException(String msg) {
  super(msg); // construtor da superclasse Exception
 }
 
}
/**
 * Falta ordenar,
 * 
 *
 */
abstract class Sortable {
   public abstract int compareTo(Sortable b);
}

class ArrayAlg {
   public static void shellSort(Sortable[] a) {
     int n = a.length;
     int incr = n / 2;
     while (incr >= 1) {
       for (int i = incr; i < n; i++) {
         Sortable temp = a[i];
         int j = i;
         while (j >= incr && temp.compareTo(a[j - incr]) < 0) {
           a[j] = a[j - incr];
           j -= incr;
         }
         a[j] = temp;
       }
       incr /= 2;
     }
   }
 }

/**
 * Classe que representa um time de futebol
 *
 */
class TimeFutebol extends Sortable {

 private String nome;
 private int PontosGanhos;
 private int GolsMarcados;
 private int GolsSofridos;
 private int SaldoDeGols;
 private int Vitorias;
 private Double GolAverage;

 public TimeFutebol(String nome1) {
  this.nome = nome1;
  this.PontosGanhos = 0;
  this.GolsMarcados = 0;
  this.GolsSofridos = 0;
  this.SaldoDeGols  = 0;
  this.Vitorias     = 0;
  this.GolAverage   = null; // considerar null se gols sofridos for 0  
 }

 @Override
 public String toString() {
  return   "Nome         : " + this.nome
       + "\nPontos Ganhos: " + this.PontosGanhos
          + "\nGols Marcados: " + this.GolsMarcados
          + "\nGols Sofridos: " + this.GolsSofridos
          + "\nSaldo de Gols: " + this.SaldoDeGols
          + "\nVitorias     : " + this.Vitorias
          + "\nGol Averages : " + ((this.GolAverage == null)? " -- " :
this.GolAverage);
 }
 public void setResult(int golsPro, int golsContra) {  
  this.GolsMarcados += golsPro;
  this.GolsSofridos += golsContra;
  
  this.SaldoDeGols = this.GolsMarcados - this.GolsSofridos;
  
  if(this.GolsSofridos > 0)
   this.GolAverage = Double.valueOf((double) this.GolsMarcados /
(double) this.GolsSofridos);
  
  if(golsPro > golsContra) {   
   this.PontosGanhos += 3;
   this.Vitorias++;
  } else if (golsPro == golsContra) {
   this.PontosGanhos++;
  }
 }

 @Override
 public int compareTo(Sortable o) {
  TimeFutebol other = (TimeFutebol)o;
  if (this.PontosGanhos > other.PontosGanhos)
   return -1;
  else if (this.PontosGanhos < other.PontosGanhos)   
   return 1;
  
  if(this.SaldoDeGols > other.SaldoDeGols)
   return -1;
  else if (this.SaldoDeGols > other.SaldoDeGols)
   return 1;
  
  return 0;
 }

}

/**
 * Classe que retorna o resultado informado pelo usuário
 * Devidamente validado
 */
class resultado{
 int [] gols     = new int[2];
 String [] times = new String[2];
 
 public resultado(String nome0, String nome1, int gol0, int gol1) {
  this.gols[0]  = gol0;
  this.gols[1]  = gol1;
  this.times[0] = nome0;  
  this.times[1] = nome1;
 }
 
 @Override
 public String toString() {
  return this.times[0] + " " + this.gols[0] + " X " + this.gols[1] + "" + this.times[1];
 }
 
}

/**
 *
 * Classe que realiza o campeonato de futebol
 *
 */
public class CampeonatoFutebol {

 private Hashtable times; // Hashtable com os times!
 
 public CampeonatoFutebol() {
  this.times = new Hashtable();
 }
 
 @SuppressWarnings("unchecked")
 public void adicionaResultado(resultado r) {
  Object o;
  TimeFutebol tf;
  
  if (!this.times.containsKey(r.times[0])) // Se não tiver o time 0, adiciona na hashtable
   this.times.put(r.times[0],new TimeFutebol(r.times[0]));
   
  if (!this.times.containsKey(r.times[1])) // Se não tiver o time 1, adiciona na hashtable
   this.times.put(r.times[1],new TimeFutebol(r.times[1]));
  
  o  = this.times.get(r.times[0]);   // Pega objeto da hashtable
  tf = (TimeFutebol) o;              // Converte no time de futebol novamente
  tf.setResult(r.gols[0],r.gols[1]); // Adiciona o resultado
  
  o  = this.times.get(r.times[1]);   // Mesma coisa com time adversario
  tf = (TimeFutebol) o;
  tf.setResult(r.gols[1],r.gols[0]); // Resultado invertido!     
 }
 
 public void show() {
  if(this.times.size() == 0) {
   JOptionPane.showMessageDialog(null,"Nenhum time cadastrado.");
   System.exit(0);
  }   
  Enumeration nomes = this.times.keys();
  while(nomes.hasMoreElements()) {
   
JOptionPane.showMessageDialog(null,this.times.get(nomes.nextElement().toString()));
  }  
 }
 
 public void sort() {
  int x=this.times.size();
  TimeFutebol [] varios_times = new TimeFutebol[x];
  
  Enumeration nomes = this.times.keys();
  for(int i=0;nomes.hasMoreElements();i++) {
   varios_times[i] = (TimeFutebol) this.times.get(nomes.nextElement());
  }
  
  ArrayAlg.shellSort(varios_times);
  
  for(int i=0;i<varios_times.length;i++) {
   System.out.println(varios_times[i]);
  }
 }
 
 /**
  * Esta classe valida o comando do usuario, retorna exception caso o
formato seja invaludo
  * @param opts
  * @return resultado do jogo
  * @throws FutebolException
  */
 public static resultado validaCmd(String [] opts) throws 
FutebolException {
  int [] gols    = {-1,-1};

  if (opts.length >< 4) //devem haver 4 campos na informação
   throw new FutebolException("O formato deve ser: time1, time2, gols1, gols2");
  else if(opts[0].length() ==0 || opts[1].length() == 0)// nome do time não pode ser vazio
   throw new FutebolException("Favor digitar os nomes dos 2 times");
  else if(opts[0].trim().equalsIgnoreCase(opts[1].trim()))  // o mesmo time jogando consigo mesmo?
   throw new FutebolException("Favor digitar 2 times diferentes");
  else if(opts[2].length() == 0 || opts[3].length() == 0) //não pode informar numero de gols vazio
   throw new FutebolException("Favor digitar o numero de gols dos 2 times");
    
  // valida formato
  try {
    gols[0]   = Integer.parseInt(opts[2].trim());
    gols[1]   = Integer.parseInt(opts[3].trim());
  } catch (Exception e) {
    gols[0]   = -1;
    gols[1]   = -1;
  }

  if(gols[0]< 0 || gols[1]<0) // analisa tanto o formato quanto o numero
   throw new FutebolException("Numero incorreto de gols!");
     
  // se tudo estiver ok...
  return new resultado(opts[0].toLowerCase().trim(),
                 opts[1].toLowerCase().trim(),
                 gols[0],
                 gols[1]);
 }

 
 @SuppressWarnings("unchecked")
 public static void main(String[] args) {
  String cmd;   
  CampeonatoFutebol cf = new CampeonatoFutebol();
    
  while(true) {
   cmd = JOptionPane.showInputDialog ("Digite o resultado do jogo, quit para terminar: ");
   
   if (cmd.trim().equalsIgnoreCase("quit"))
    break; // para sair do loop
   
   String [] opts = cmd.split(","); // 'splita' o resultado em torno de virgulas
      
   try {
    resultado r = validaCmd(opts); // valida resultado
    
    JOptionPane.showMessageDialog(null,r.toString()); // DEBUG, pode comentar
    
    cf.adicionaResultado(r);
    
   } catch (FutebolException e) {
    //JOptionPane.showMessageDialog(null,e.getMessage());
    System.err.println(e.getMessage());
   }        
  }
  
  cf.sort();
  
  //cf.show(); faltaaaaaaaaaa
  
  // cf.imprime(); faltaaaaaa
  
  System.exit(0);  
 }

}[/code]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Vc quem deve implementar a ordenação?!
Já existem utilitários prontos de java.util que faz isso, por exemplo TreeMap!

Ok. Me ajude a te ajudar:

  1. O que vc quer ordenar: Um array simples("[]")? Um ArrayList? Um HashTable?
  2. Que tipo de dado está armazenado na “lista” que vc quer ordenar: String? Date? Object? TimeFutebol? resultado?
    Espero sua resposta.

[color=plum]Ei gente, acabei de chegar da facul, tava tentando fazer lah esse ep…
Muito obrigada pela ajudaaaaaa! Fiquei muito feliz, vou trocar o código lah viu, e ver como as coisas vão andando!!!
Bjins!
[/color]

Mas não adianta muito usar o TreeMap se os objetos nele inseridos não pertencerem a uma classe que implemente a interface java.lang.Comparable, ou então se esse TreeMap não for instanciado passando para seu construtor um objeto que implemente java.util.Comparator que faça a comparação de forma adequada.
No caso do código da Lilian, ela criou ali uma classe Sortable que não vai servir pra nada ao se utilizar o TreeMap. Isso porque TreeMap, quando vai fazer a ordenação dos objetos nele contidos, espera ou que eles implementem java.lang.Comparable ou que o java.util.Comparator passado em seu construtor saiba ordenar esses objetos. Se nenhuma dessas opções for verdadeira, vai dar um ClassCastException no exato momento em que for inserido o segundo elemento do TreeMap.

[color=plum]Heheheh, é verdade, eu troquei o código mas não adiantou nada, tive que desfazer… tive que entregar o programa do jeito que tava porque nao consegui mudar nada…[/color]

É uma pena… Mas de qq forma, tenta fazer ele agora, pra praticar! :thumbup:
QQ dúvida que tiver, poste novamente, ok?

[color=plum]É verdade vou tentar fazer direitinho pra aprender, e obrigada pela ajuda![/color]

Boa tarde!
Sugiro fazer o seguinte teste:

[code]public class CampeonatoFutebol {

private TreeMap times; // TreeMap com os times!

public CampeonatoFutebol() {
this.times = new TreeMap();
}[/code]

Espero que ajude!