Informações do array impressas de forma incorreta

Bom dia!

Sou iniciante em Java e estou precisando de ajuda.

Vou postar todo o código com o maior número possível de informações pois estou precisando de ajuda para entender melhor.

Criei um programa que permite digitar o nome do arquivo.txt que será lido.

@MSSantana

Boa noite, li seu código mas não consegui acompanhar seu raciocínio então fiz minha versão do exercício usando a forma mais acadêmica. Existem recursos mais modernos dentro da linguagem que tornam tudo bem mais simples.

Classe principal do sistema.

import javax.swing.*;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;

public class Principal {

    public static void main(String[] args) throws IOException {
        start(JOptionPane.showInputDialog("Informe o nome do arquivo .txt existente nesse diretório a ser lido:" + "\n" + "Exemplo: conteudo.txt"));
    }

    public static void start(String fileName) {
        try {
            //"../TreinandoJava/src/" + fileName;
            new Game(new File(("../Testes/src/main/resources/" + fileName))).start();
        } catch (FileNotFoundException fileNotFoundException) {
            System.out.println("Arquivo não encontrado");
        }
    }
}

Classe que contém toda a lógica para organização dos dados.

import java.io.*;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;

public class Game {

    private final BufferedReader bufferedReader;
    private final List<Tournament> tournaments;
    private final List<PlayerScore> ranking;
    private final Map<Date, Integer> conflitingTournamentDates;

    public Game(File file) throws FileNotFoundException {
        this.bufferedReader = new BufferedReader(new FileReader(file));
        this.tournaments = new ArrayList();
        this.ranking = new ArrayList();
        this.conflitingTournamentDates = new HashMap();
    }

    public void start() {
        try {
            readFile(); //lê cada linha do arquivo e coloca dentro de uma lista ordenando por data
            listRanking(); //monta um ranking usando a lista de torneios e ordenando por pontuação
            findConflitingTournamentDates(); //procura datas conflitantes dentro da lista de torneios
            printBiggestScore(); //imprime maior pontuação dentro do ranking
            printBiggestPrize(); //imprime maior prêmio dentro do ranking
            printRanking(); //imprime todo o ranking
            printConflitingTournamentDates(); //imprime resumo e datas conflitantes dentro da lista de torneio
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    private void readFile() throws IOException {
        while (bufferedReader.ready()) {
            String line = bufferedReader.readLine();
            if (line != null) tournaments.add(new Tournament(line.split("/")));
        }
        bufferedReader.close();
        Collections.sort(tournaments);
    }

    private void listRanking() {
        for (Tournament tournament : tournaments) {
            boolean exist = false;
            if (ranking.size() > 0) {
                for (PlayerScore playerScore : ranking) {
                    if (playerScore.getPlayerName().equals(tournament.getWinner())) {
                        playerScore.setTotalPoints(playerScore.getTotalPoints() + tournament.getTypeValue());
                        playerScore.setVictories(playerScore.getVictories() + 1);
                        playerScore.setPrize(playerScore.getPrize().add(tournament.getPrizeValue()));
                        exist = true;
                        break;
                    }
                }
            }
            if (!exist) {
                ranking.add(new PlayerScore(tournament.getWinner(), tournament.getTypeValue(), 1, tournament.getPrizeValue()));
            }
        }
        Collections.sort(ranking);
    }

    private void findConflitingTournamentDates() {
        for (Tournament tournament : tournaments) {
            boolean exist = false;
            if (conflitingTournamentDates.containsKey(tournament.getDate())) {
                conflitingTournamentDates.put(tournament.getDate(), conflitingTournamentDates.get(tournament.getDate()) + 1);
                exist = true;
            }
            if (!exist) {
                conflitingTournamentDates.put(tournament.getDate(), 1);
            }
        }
    }
    

    private void printBiggestScore() {
        System.out.println("Jogador com o maior nº de pontos:");
        PlayerScore biggestScore = ranking.get(0);
        for (PlayerScore score : ranking) {
            if (score.getTotalPoints() > biggestScore.getTotalPoints()) {
                biggestScore = score;
            }
        }
        System.out.println(String.format("%s - %s\n", biggestScore.getPlayerName(), biggestScore.getTotalPoints()));
    }

    private void printBiggestPrize() {
        DecimalFormat decimalFormat = new DecimalFormat("#,###.00");
        System.out.println("Jogador com maior valor em premiação:");
        PlayerScore biggestPrize = ranking.get(0);
        for (PlayerScore score : ranking) {
            if (score.getPrize().compareTo(biggestPrize.getPrize()) == 1) {
                biggestPrize = score;
            }
        }
        System.out.println(String.format("%s -  $ %s\n", biggestPrize.getPlayerName(), decimalFormat.format(biggestPrize.getPrize())));
    }

    private void printRanking() {
        System.out.println("Ranking Atual dos Jogadores:\nNome Jogador - Total de Pontos - Nº de Vitórias\n");
        for (PlayerScore score : ranking) System.out.println(score.toString());
    }

    private void printConflitingTournamentDates() {
        System.out.println("\nTorneios com Datas Conflitantes:");
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd-MM-yyyy");
        TreeMap<Date, Integer> treeMap = new TreeMap(conflitingTournamentDates);
        for (Map.Entry<Date, Integer> entry : treeMap.entrySet()) {
            if (entry.getValue() > 1) {
                System.out.println(String.format("%s - %s", simpleDateFormat.format(entry.getKey()), entry.getValue().toString()));
            }
        }
        System.out.println("");
        for (Map.Entry<Date, Integer> entry : treeMap.entrySet()) {
            if (entry.getValue() > 1) {
                for (Tournament tournament : tournaments) {
                    if (tournament.getDate().equals(entry.getKey())) {
                        System.out.println(String.format("%s - %s", simpleDateFormat.format(tournament.getDate()), tournament.getWinner()));
                    }
                }
            }
        }
    }

}

Classe que representa cada linha do arquivo.

import java.math.BigDecimal;

public class PlayerScore implements Comparable<PlayerScore> {

    private String playerName;
    private Integer totalPoints;
    private Integer victories;
    private BigDecimal prize;

    public PlayerScore(String playerName, Integer totalPoints, Integer victories, BigDecimal prize) {
        this.playerName = playerName;
        this.totalPoints = totalPoints;
        this.victories = victories;
        this.prize = prize;
    }

    public String getPlayerName() {
        return playerName;
    }

    public Integer getTotalPoints() {
        return totalPoints;
    }

    public void setTotalPoints(Integer totalPoints) {
        this.totalPoints = totalPoints;
    }

    public Integer getVictories() {
        return victories;
    }

    public void setVictories(Integer victories) {
        this.victories = victories;
    }

    public BigDecimal getPrize() {
        return prize;
    }

    public void setPrize(BigDecimal prize) {
        this.prize = prize;
    }

    @Override
    public String toString() {
        return playerName + "  " + totalPoints + " " + victories;
    }

    @Override
    public int compareTo(PlayerScore playerScore) {
        if (playerScore.getTotalPoints() == totalPoints) return 0;
        return playerScore.getTotalPoints() < totalPoints ? -1 : 1;
    }

}

Classe que representa o Torneio

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Tournament implements Comparable<Tournament> {

    private Date date;
    private Integer d;
    private String locale;
    private String type;
    private Integer typeValue;
    private String currency;
    private BigDecimal prizeValue;
    private String winner;

    public Tournament(String[] values) {
        try {
            date = new SimpleDateFormat("dd-MM-yyyy").parse(values[0]);
            d = Integer.parseInt(values[1]);
            locale = values[2];
            type = values[3].substring(0, 3).toUpperCase();
            typeValue = type.equals("ATP") ? Integer.parseInt(values[3].substring(3)) : 2000;
            prizeValue = new BigDecimal(values[4].split(" ")[0]);
            currency = values[4].split(" ")[1];
            winner = values[5];
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public Date getDate() {
        return date;
    }

    public Integer getTypeValue() {
        return typeValue;
    }

    public BigDecimal getPrizeValue() {
        return prizeValue;
    }

    public String getWinner() {
        return winner;
    }

    @Override
    public String toString() {
        return "Tournament{" +
                "date=" + date +
                ", d=" + d +
                ", locale='" + locale + '\'' +
                ", type='" + type + '\'' +
                ", typeValue=" + typeValue +
                ", currency='" + currency + '\'' +
                ", prizeValue=" + prizeValue +
                ", winner='" + winner + '\'' +
                '}';
    }

    @Override
    public int compareTo(Tournament tournament) {
        if (tournament.getDate().equals(date)) return 0;
        return tournament.getDate().after(date) ? -1 : 1;
    }

}

Muito obrigada pela ajuda @Villagram !!

Uma dúvida que eu fiquei.

Nos casos da pontuação do ranking, quando temos empates de vitórias e pontuação, como seria a para o print ser em ordem alfabética pelo nome?

Muito obrigada mesmo!

@Villagram

Testando com esse arquivo:

20-01-2020/14/Melbourne/Grand Slam/11633160 $/N. Djokovic
21-02-2020/7/Dubai/ATP500/2950420 $/N. Djokovic
03-02-2020/6/Cordoba/ATP250/610000 $/C. Garin
16-02-2020/7/Rio de Janeiro/ATP500/1915485 $/C. Garin
03-02-2020/6/Montpellier/ATP250/606350 $/G. Monfils
10-02-2020/7/Rotterdam/ATP500/2155295 $/G. Monfils
06-01-2020/6/Doha/ATP250/1465260 $/A. Rublev
12-01-2020/6/Adelaide/ATP250/610000 $/A. Rublev
21-02-2020/7/Acapulco/ATP500/2000845 $/R. Nadal
10-02-2020/6/Buenos Aires/ATP250/696280 $/C. Ruud
03-02-2020/6/Pune/ATP250/610000 $/J. Vesely
10-02-2020/6/New York/ATP250/804180 $/K. Edmund
17-02-2020/6/Delray Beach/ATP250/673655 $/R. Opelka
17-02-2020/6/Marseille/ATP250/769670 $/S. Tsitsipas
21-02-2020/6/Santiago/ATP250/604010 $/T. Seyboth Wild
13-01-2020/6/Auckland/ATP250/610000 $/U. Humbert

A saída foi:

N. Djokovic  2500 2
C. Garin  750 2
G. Monfils  750 2
A. Rublev  500 2
R. Nadal  500 1
U. Humbert  250 1
J. Vesely  250 1
C. Ruud  250 1
K. Edmund  250 1
R. Opelka  250 1
S. Tsitsipas  250 1
T. Seyboth Wild  250 1

E deveria ser:

N. Djokovic  2500 2
C. Garin  750 2
G. Monfils  750 2
A. Rublev  500 2
R. Nadal  500 1
C. Ruud  250 1
J. Vesely  250 1
K. Edmund  250 1
R. Opelka  250 1
S. Tsitsipas  250 1
T. Seyboth Wild  250 1
U. Humbert  250 1

Vi que tem um Collection.sort(ranking), mas parece que isso não foi suficiente para resolver e conseguir ordenar.

Tentei mexer em algumas coisas, mas como ainda sou iniciante, não consegui.

Poderia me ajudar?

Mt obrigada!

Bom dia

Eu estava montando um exemplo em casa o método que você precisa mexer é o “compareTo” que está dentro da classe “PlayerScore”, dentro desse método está a maneira como o “Collection.sort” faz para ordenar o ranking.

Vou montar só esse trecho de código para você substituir.

Bom dia, desculpe a demora. Para fazer a organização como vc quer basta substituir esse método na classe “PlayerScore”.

@Override
    public int compareTo(PlayerScore playerScore) {
        int compareInt = Integer.compare(playerScore.getTotalPoints(), totalPoints);
        if (compareInt == 0) {
            return playerName.compareTo(playerScore.getPlayerName()) > 0 ? 1 : -1;
        }
        return compareInt;
    }

Para entender o que fiz: Esse método mostra para o método “Collections.sort” como fazer a organização dos valores para esta classe sendo:

0 = os valores são iguais;
1 = o valor é maior que;
-1 = o valor é menor que;

Strings já tem um método “compareTo” que faz a subtração do valor das strings em char que não usa 0 e 1 mas se o resultado é maior ou menor que 0. Para fazer a organização que você pediu fiz o seguinte:

Caso os valores da pontuação forem iguais eu verifico os nomes e se a subtração for maior que 0 retorna 1 e menor -1, se forem iguais retorna o valor da comparação dos pontos.

1 curtida