Domanda Restituire elenco registrazioni di una certa tipologia in base a parametro -Java

jr_sottomajor

Utente Silver
2 Luglio 2017
96
33
4
79
Ciao a tutti, riguardo questo esercizio java la cui traccia è:
domanda.png

Esclusi il secondo e l'ultimo punto che ho già svolto, ho alcune domande sui rimanenti 3 punti. Riguardo il primo per poter ordinare la lista rispetto al cognome dovrei implementare l'interfaccia Comparable tramite la classe Registrazione? Sovrascriverei il metodo compareTo(Registrazione r) in questo modo:
Java:
public int compareTo(Registrazione r){
    return this.cognome.compareTo(r.getCognome());
}
Premetto che la classe Registrazione è astratta e la estendono 2 classi: Studente e Professionista. Immagino che dovrei implementare l'interfaccia tramite la superclasse e in automatico le sottoclassi ereditano il metodo compareTo(?).
Riguardo il 3 e il 4 punto diciamo che sono un po la stessa cosa, riuscendo a fare il 3 farei automaticamente anche il 4. Il dubbio è il seguente: come faccio a capire da una lista di Registrazione quali appartengono a Studente e quali a Professionista? Ho tentato di risolvere comparando banalmente il nome della classe, ovvero:
Java:
public ArrayList<Registrazione> dammiRegistrazionePerTipoPartecipante(int x){
        ArrayList<Registrazione> ritorno=new ArrayList<>();
        if(x==0) {
            for(Registrazione r:registrazioni) {
                if(r.getClass().getName().substring(12).equals("Studente"))
                    ritorno.add(r);
            }
        }else if(x==1) {
            for(Registrazione r:registrazioni) {
                if(r.getClass().getName().substring(12).equals("Professionista"))
                    ritorno.add(r);
            }
            
        }else {
            throw new InvalidParameterException();
        }
        return ritorno;
        
    }
(Il substring lo uso perche le classi si trovano in un package e quindi elimino la parte "package.NomeClasse").. Immagino sia sbagliato un procedimento del genere, almeno da un punto di vista di riusabilità del codice. Come potrei quindi fare? Grazie in anticipo
 
Riguardo il primo per poter ordinare la lista rispetto al cognome dovrei implementare l'interfaccia Comparable tramite la classe Registrazione? Sovrascriverei il metodo compareTo(Registrazione r) in questo modo:
Java:
public int compareTo(Registrazione r){
return this.cognome.compareTo(r.getCognome());
}
Premetto che la classe Registrazione è astratta e la estendono 2 classi: Studente e Professionista. Immagino che dovrei implementare l'interfaccia tramite la superclasse e in automatico le sottoclassi ereditano il metodo compareTo(?).
Sì. Oppure, invece che ordinare ogni volta (operazione lenta) puoi preoccuparti di inserire ogni nuovo elemento in ordine: lo aggiungi alla fine e poi lo shifti a sinistra con una serie di swap come faresti nel ciclo interno dell'insertion sort. Ricordati di quella RegistrationException.

Riguardo il 3 e il 4 punto diciamo che sono un po la stessa cosa, riuscendo a fare il 3 farei automaticamente anche il 4. Il dubbio è il seguente: come faccio a capire da una lista di Registrazione quali appartengono a Studente e quali a Professionista? Ho tentato di risolvere comparando banalmente il nome della classe, ovvero:
Java:
public ArrayList<Registrazione> dammiRegistrazionePerTipoPartecipante(int x){
ArrayList<Registrazione> ritorno=new ArrayList<>();
if(x==0) {
for(Registrazione r:registrazioni) {
if(r.getClass().getName().substring(12).equals("Studente"))
ritorno.add(r);
}
}else if(x==1) {
for(Registrazione r:registrazioni) {
if(r.getClass().getName().substring(12).equals("Professionista"))
ritorno.add(r);
}

}else {
throw new InvalidParameterException();
}
return ritorno;

}
(Il substring lo uso perche le classi si trovano in un package e quindi elimino la parte "package.NomeClasse").. Immagino sia sbagliato un procedimento del genere, almeno da un punto di vista di riusabilità del codice. Come potrei quindi fare?
Puoi usare instanceof, una roba del genere
Java:
ArrayList<Registrazione> dammiRegistrazionePerTipoPartecipante(int x) {
    if (x != 0 && x != 1) throw new InvalidParameterException("Bad kind");
    return r.stream().filter(i -> x == 0 ? i instanceof Studente : i instanceof Professionista).collect(Collectors.toList());
}
Ricordati che puoi usare dammiRegistrazionePerTipoPartecipante e un metodo privato (e.g. private double calcolaTotale(ArrayList<Registrazione> lst)) per implementare il punto 2 e il punto 4 senza riscrivere codice.
 
Ultima modifica:
A quanto pare devo proprio mettermi seriamente sulle espressioni lamba :D . Per quanto riguarda aggiungiRegistrazione da ordinare in base al cognome ho usato il metodo piu lento :
Java:
public void aggiungiRegistrazione(Registrazione r) {
        for(Registrazione z:registrazioni) {
            if(z.getNome()==r.getNome() && z.getCognome()==r.getCognome()) {
                throw new RegistrationException();
        }else {
            registrazioni.add(z);
            Collections.sort(registrazioni);
        }
    }
}
Immagino sia fatta bene(?), cioè ad ogni iterazione fa il sort per ordinare. L'altro modo che mi hai suggerito non l'ho ancora messo in pratica, ma dovrebbe essermi chiaro. Riguardo l'instanceof lo conoscevo, semplicemente lo usavo come fosse un metodo e non lo trovava .. mia svista. Ho fatto quindi cosi:
Java:
public ArrayList<Registrazione> dammiRegistrazionePerTipoPartecipante(int x){
        ArrayList<Registrazione> ritorno=new ArrayList<>();
        if(x==0) {
            for(Registrazione r:registrazioni) {
                if(r instanceof Studente)
                    ritorno.add(r);
                    
            }
        }else if(x==1) {
            for(Registrazione r:registrazioni) {
                if(r instanceof Professionista)
                    ritorno.add(r);
            }
            
        }else {
            throw new InvalidParameterException();
        }
        return ritorno;
        
    }

Dovrebbe essere tutto ok per ora. L'ultima parte dell'esercizio è l'implementazione di una GUI.. e sicuramente avrei da fare delle domande anche li. Per ora posto solo la traccia :
gui1 .png

gui2.png

Messaggio unito automaticamente:

Ciao, sto provando a svolgere la parte grafica dell'esercizio. Per ora ho fatto il punto a e avrei dei dubbi su come proseguire. Posto intanto il codice:
Java:
package appello2401;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Scanner;

import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;



public class FrameViewer extends JFrame{
    public FrameViewer() {
        createField();
        createButton();
        createPanel();
        setSize(400,500);
    }
    
    private void createField() {
        label=new JLabel("Nome file: ");
        field=new JTextField(10);
    }

    public void createButton() {
        button=new JButton("Carica");
        class Carica implements ActionListener{
            
            public void actionPerformed(ActionEvent e) {
                try {
                    f=new FileReader(field.getText());
                    sc=new Scanner(f);
                    String input=sc.nextLine();
                } catch (FileNotFoundException e1) {
                    field.setText("File non esistente");
                }
                new FrameViewer2();
            }
        }
        
        ActionListener listener=new Carica();
        button.addActionListener(listener);
    }
    
    private void createPanel() {
        JPanel panel=new JPanel();
        panel.add(label);
        panel.add(field);
        panel.add(button);
        add(panel);
    }

    
    //var istanza
    private JButton button;
    private JTextField field;
    private JLabel label;
    private FileReader f;
    private Scanner sc;
}

I dubbi sono due:
1)per fare in modo che cliccando un tasto si apre una nuova schermata il metodo che ho usato io di creare una nuova classe è giusto? Il problema è che poi passando il controllo alla seconda classe questa non può accedere alle variabili della prima. Dovrei crearla come sottoclasse?
2)Dovendo poi istanziare le registrazioni su un file come faccio poi ad importarle nel programma? Cioè se nel file scrivo "Mario Rossi, Università di milano, triennale, 20/01/2020" come leggo parametro per parametro per creare poi gli oggetti? Nel senso potrei prendere la prima parola prima di uno spazio per il nome, poi il resto fino alla prima virgola per il cognome, il resto fino alla seconda virgola per il nome dell'università ecc.(?) Grazie in anticipo