Esercizio: Lista Circolare Si realizzi in Java un gestore di una lista circolare. La dimensione minima della lista è 2 elementi (ed è anche la dimensione iniziale). La dimensione massima è 20 elementi. Il gestore della lista deve consentire di cercare, aggiungere e rimuovere elementi. Ogni elemento della lista contiene le informazioni su un frame, ossia l elemento base di un flusso di dati multimediali. Il frame può essere audio o video.
Esercizio: Lista Circolare Ogni frame audio è caratterizzato da: nome dello stream numero di sequenza (un intero positivo) bitrate (un intero positivo multiplo di 16) codifica (una String tipo MPEG Layer 3, Dolby AAC, ecc.) flag mono/stereo Ogni frame video è caratterizzato da: nome dello stream numero di sequenza (un intero positivo) bitrate (un intero multiplo di 24) standard (una String tipo PAL, HDTV, ecc.) codifica (una String tipo MPEG4, H.264, ecc.)
Esercizio: Lista Circolare Inserimento degli elementi: Ogni frame audio può essere inserito nella lista solo se appartiene allo stesso stream ed ha la medesima codifica di quelli già presenti. Analogamente, un frame video può essere inserito solo se ha medesimo nome dello stream, della codifica e dello standard rispetto agli altri elementi della lista. Inoltre, ad ogni frame inserito deve essere associato un numero di sequenza ottenuto incrementando di una unità il numero di sequenza dell ultimo frame dello stesso tipo inserito.
Esercizio: Lista Circolare La funzione di inserimento di un frame nella lista circolare deve inoltre garantire che partendo da un certo elemento, sia possibile percorrere l intera struttura osservando un andamento crescente dei numeri di sequenza dei frame dello stesso tipo. 8 12 6 partendo da qui, i frame hanno numero di sequenza crescente 6 7 n Frame Audio 5 11 3 n Frame Video
Esercizio: Lista Circolare Ricerca degli elementi: La funzione di ricerca deve permettere la ricerca di un frame sulla base di almeno un parametro distintivo dell oggetto. Ad esempio, il numero di sequenza.
Analisi delle specifiche Lista: elenco dinamico di elementi. L attributo dinamico indica che la lista non ha numero fisso di elementi. Nel nostro esempio, sulla lista sono specificati vincoli e proprietà: il numero minimo (2) e massimo (20) di elementi le operazioni che è possibile svolgere sulla lista
Analisi delle specifiche La lista deve contenere degli elementi. Gli elementi della lista sono entità che contengono informazioni su altre entità dette Frame. In particolare, sono considerati due tipi specifici di Frame: i Frame Audio i Frame Video
Implementazione Dobbiamo implementare tre entità: 1. La lista 2. I nodi della lista 3. I frame, ossia le entità contenute nei nodi.
Il Frame Le entità di cui dobbiamo tenere traccia nella lista sono i frame. Sono definiti due tipi di frame, i quali condividono caratteristiche comuni. Frame Frame Audio Frame Video Li modelliamo perciò in Java come sottoclassi di una classe comune.
La classe Frame public abstract class Frame { protected String nomestream, codifica; protected int sequencenum, bitrate; public int getbitrate() { return bitrate; public String getcodifica() { return codifica; public String getnomestream() { return nomestream; public int getsequencenum() { return sequencenum; public void setsequencenum(int sequencenum) { this.sequencenum = sequencenum;
La sottoclasse AudioFrame public class AudioFrame extends Frame { private boolean isstereo; public AudioFrame(String nomestream, String codifica, int bitrate, boolean stereo) throws FrameException { if ((bitrate % 16!= 0) (bitrate <= 0)) throw new FrameException("wrong audio bitrate"); this.nomestream = nomestream; this.codifica = codifica; this.bitrate = bitrate; isstereo = stereo; public boolean isstereo() { return isstereo;
Il Nodo Il nodo è l elemento che costituisce la lista. Ciascun nodo contiene: L oggetto Frame che deve descrivere Il riferimento al nodo successivo node frame node frame next node next node
La classe Nodo public class Nodo { private Frame framedata; private Nodo nextnodo; public Nodo(Frame frame) { framedata = frame; public Nodo getnextnodo() { return nextnodo; public void setnextnodo(nodo nextnodo) { this.nextnodo = nextnodo; public Frame getframedata() { return framedata;
La classe Lista public class ListaCircolare { private Nodo lastelement; private int nsequencevideoframe, nsequenceaudioframe; private String codificaaudio, codificavideo, stream; public ListaCircolare(Frame firstelement, Frame secondelement) throws ListException { [corpo del costruttore vedi slide successive]
La Lista costruttore (1) public ListaCircolare(Frame firstelement, Frame secondelement) throws ListException { if (! firstelement.getnomestream().equalsignorecase( secondelement.getnomestream() ))) throw new ListException("Frame di stream diversi"); lastelement = new Nodo(secondElement); Nodo temp = new Nodo(firstElement); lastelement.setnextnodo(temp); temp.setnextnodo(lastelement);
La Lista costruttore (1) Nodo lastelement Nodo temp Frame secondelement nextnodo Fame firstelement nextnodo
La Lista costruttore (2) if (firstelement instanceof VideoFrame) { if (secondelement instanceof VideoFrame) { if (!firstelement.getcodifica().equalsignorecase(secondelement.getcodifica() )) throw new ListException("Codifiche video incompatibili"); firstelement.setsequencenum(1); secondelement.setsequencenum(2); nsequencevideoframe = 2; nsequenceaudioframe = 0; else { firstelement.setsequencenum(1); secondelement.setsequencenum(1); nsequencevideoframe = 1; nsequenceaudioframe = 1; codificavideo = firstelement.getcodifica(); codificaaudio = secondelement.getcodifica();
La Lista costruttore (3) else { if (secondelement instanceof VideoFrame) { firstelement.setsequencenum(1); secondelement.setsequencenum(1); nsequencevideoframe = 1; nsequenceaudioframe = 1; codificavideo = secondelement.getcodifica(); codificaaudio = firstelement.getcodifica(); else { if (!firstelement.getcodifica().equalsignorecase(secondelement.getcodifica() )) throw new ListException("Codifiche audio incompatibili"); firstelement.setsequencenum(1); secondelement.setsequencenum(2); nsequencevideoframe = 0; nsequenceaudioframe = 2;
La Lista inserimento Frame public void insertframe(frame f) throws ListException { if (f instanceof VideoFrame) { if (! f.getcodifica().equalsignorecase(codificavideo)) throw new ListException("Codifica video non compatibile"); f.setsequencenum(++nsequencevideoframe); else { if (! f.getcodifica().equalsignorecase(codificaaudio)) throw new ListException("Codifica audio non compatibile"); f.setsequencenum(++nsequenceaudioframe); Nodo nuovonodo = new Nodo(f); nuovonodo.setnextnodo(lastelement.getnextnodo()); lastelement.setnextnodo(nuovonodo); lastelement = nuovonodo;
La Lista inserimento Frame Nodo lastelement Frame secondelement nextnodo Frame firstelement nextnodo Nodo nuovonodo Nodo lastelement Frame f nextnodo
La Lista metodo di ricerca public VideoFrame searchvideoframe(int sequencenum) { if (sequencenum > nsequencevideoframe) return null; else { VideoFrame result = null; Nodo temp = lastelement; boolean prosegui = true; while (prosegui) { try { result = (VideoFrame)temp.getNextNodo().getFrameData(); if (result.getsequencenum() == sequencenum) prosegui = false; catch (ClassCastException e) { temp = temp.getnextnodo(); if (temp == lastelement.getnextnodo()) prosegui = false; return result;
ArrayList La classe ArrayList implementa un array dinamico, a cui è possibile aggiungere elementi senza che sia stabilita una dimensione massima in pratica, esibisce il comportamento di una lista. Rispetto a Vector (classe del package java.util), i metodi non sono synchronized e pertanto sono più veloci non dovendo garantire la mutua esclusione nell accesso ai dati gestiti dall istanza di Vector ArrayList gestisce internamente un array di Object: possono essere quindi inseriti oggetti di qualunque tipo
ArrayList - svantaggi Internamente, ArrayList si poggia su un array classico : nel caso siano inseriti elementi in eccesso, viene generato un nuovo array di dimensioni maggiori in cui sono copiati i valori dell array iniziale per poi aggiungere i nuovi dati. Tale processo può diventare pesante per liste che variano frequentemente ed in maniera significativa Il metodo get(int index) restituisce l elemento in posizione index: essendo però la lista formata da elementi di classe Object, l elemento ritornato è di classe Object e può essere ricondotto alla classe reale (se diversa da Object) attraverso un cast esplicito. Ciò però richiede la conoscenza della classe dell elemento estratto!
ArrayList accesso agli elementi ArrayList list = new ArrayList(); Integer numero = new Integer(10); String nome = new String( Diego"); list.add(numero); list.add(nome); Integer recuperanumero = (Integer)list.get(0); String recuperanome = (String)list.get(1); if (list.get(0) instanceof Integer) System.out.println( Numero!"); else System.out.println( Nooooo"); if (list.get(1) instanceof String) System.out.println( Nome! ); else System.out.println( Nooooo );