Salve, ho un esercizio con questa traccia:

codice:
Chiave con un solo metodo valore( ) che restituisce un intero;• OggettoConChiave con metodi:
     - restituisciChiave() che restituisce un oggetto di tipo Chiave;
     - restituisciId() che restituisce una stringa.
• CollezioneConChiave con parametro T compatibile con OggettoConChiave e
metodi:
    - seleziona(Chiave x, Chiave y) che restituisce un ArrayList contenente tutti gli oggetti di tipo T con valore di chiave tra quelli di x e y, se il valore associato a y è minore di quello associato ad x deve essere lanciata un’eccezione non controllata opportuna;
    - inserisci(T z) che aggiunge z alla collezione;
    - rimuovi(Chiave x) che rimuove un oggetto con chiave x;


2. Implementare in Java il concetto di agenda come una collezione di tipo CollezioneConChiave in cui le chiavi sono intervalli chiusi tra due date e gli oggetti memorizzati sono gli appuntamenti.
In particolare, un oggetto IntervalloData ha una data di inizio e una data di fine (le date sono con ora, giorno, mese e anno).
Un oggetto Appuntamento ha una descrizione e un intervallo di date.
L’interfaccia pubblica della classe Agenda deve contenere anche un metodo predicativo checkAvailability(IntervalloData x) che restituisce vero se e solo se l’intervallo di date x
non si sovrappone agli intervalli degli appuntamenti in agenda.
Inoltre, l’invocazione inserisci(z) deve lanciare un’eccezione UnavailableIntervalException se l’intervallo di z si sovrappone con quello di un altro appuntamento già in agenda (nel caso in cui viene lanciata l’eccezione l’appuntamento non deve essere inserito).
non riesco a capire praticamente come strutturare il codice
Ho iniziato in questo modo:
codice:
public class Chiave {
    Appuntamento app;
    public Chiave(Appuntamento app){
        this.app=app;
    }
    
    public Chiave(){
    }
    
    public int valore(){
        return 1;
    }
}


public class OggettoChiave {
    public Chiave restituisciChiave(){
        return new Chiave();
    }
    
    public String restituisciId(){
        return "Id";
    }
}


public class CollezioneConChiave<T> {
    
    public ArrayList<T> seleziona(Chiave x, Chiave y){
        ArrayList<T> a=new ArrayList<T>();
        if(y.valore()<x.valore()){
            throw new RuntimeException();
        }
        return a;
    }
    
    public void inserisci(T z){
        //inserisci T all'arraylist
    }
    
    public void rimuovi(Chiave x){
        //rimuove un oggetto con Chiave x dall'arraylist
    }


}


public class agenda {
    ArrayList<CollezioneConChiave> coll=new ArrayList<CollezioneConChiave>();
    
    public boolean checkAvailability(IntervalloData x){
       //IL CONFRONTO CON QUALI ELEMENTI LO DEVO FARE???????
        return true;
    }
}


public class Appuntamento {
    public String descrizione;
    public IntervalloData inte;
    public Appuntamento(IntervalloData inte,String desc){
        this.inte=inte;
        this.descrizione=desc;
    }
}


public class IntervalloData {
    public int gg,mm,yy,ora,g,m,y,h;
    
    public IntervalloData(int gg,int mm,int yy,int ora,int g,int m,int y,int h) {
        this.gg=gg;
        this.mm=mm;
        this.yy=yy;
        this.ora=ora;
        /*    data di fine    */
        this.g=g;
        this.m=m;
        this.y=y;
        this.h=h;
    }


}

ma non ne riesco a venire a capo...
Come posso strutturare l'esercizio?