Tree<V>
per rappresentare
alberi tali che
ad ogni nodo è associato un valore di tipo generico V
.
La classe deve definire una classe annidata statica Tree.Node<V>
per rappresentare i nodi dell'albero. Tale classe deve essere pubblica
e deve avere
solamente due metodi pubblici (può avere altri metodi o costruttori ma
devono
essere privati):
public V getValue()
ritorna
il
valore associato al nodopublic void setValue(V v)
associa
il valore v
al nodo.Tree<V>
deve definire i seguenti
costruttore e metodi.
v
e
crea un albero
composto dalla sola radice a cui è associato il valore v
.Tree.Node<V>
).u
e
ritorna true
se e solo se il nodo u
appartiene all'albero.u
e
ritorna il nodo
padre
di u
(se u
è la radice ritorna null
).
Se u
non appartiene all'albero lancia un'eccezione IllegalArgumentException
.Set<Tree.Node<V>>
getChildren(Tree.Node<V> u)
che ritorna una vista non
modificabile dell'insieme dei nodi figli di u
. Se u
non
appartiene all'albero lancia un'eccezione IllegalArgumentException
.Tree.Node<V>
addChild(Tree.Node<V> u, V v)
che aggiunge all'albero un nuovo nodo come figlio del nodo u
,
con valore
associato v
, e ritorna il nuovo nodo. Se u
non appartiene all'albero lancia un'eccezione IllegalArgumentException
.Iterable<Tree.Node<V>>
per iterare sui nodi dell'albero. L'iteratore ritornato non deve
supportare il
metodo remove()
. Set<...>
,
parametrizzato in modo che gli elementi implementino l'interfaccia Comparable
,
e un elemento x
, ritorna sia il predecessore che il
successore di x
nell'insieme.
Definire un opportuno tipo generico per rappresentare l'output del
metodo. Il successore di x
è il più piccolo elemento dell'insieme che è strettamente maggiore di x
,
se x
è maggiore od uguale al massimo dell'insieme allora
è null
.
Il predecessore di x
è il più grande elemento
dell'insieme che è strettamente minore di x
, se x
è minore od uguale al minimo dell'insieme
allora è null
. import java.util.*;
public class Test {
public static void main(String[] args) {
List<List<String>> sLL = new ArrayList<List<String>>();
sLL.add(new LinkedList<String>());
LinkedList<String> linked = sLL.get(0);
ArrayList<String>[] lsA = new ArrayList<String>[10];
List<? extends Comparable<String>> csL;
csL = sLL.get(0);
sLL.add(csL);
}
}
E
) intendiamo
un qualsiasi tipo che
implementa la seguente interfaccia:
public interface GSet<E> extends Iterable<E> {Ad esempio, una classe che rappresenta un insieme generico di stringhe potrebbe chiamarsi
boolean contains(E x); // Ritorna true se x appartiene all'insieme generico
}
StrGSet
e implementare GSet<String>
.
Si vuole definire una classe generica per gestire insiemi di insiemi
generici disgiunti con elementi dello
stesso tipo. La classe ha un solo parametro di tipo E
che
rappresenta il tipo degli elementi degli insiemi
generici. La classe deve definire i seguenti costruttori e metodi.
true
.
Altrimenti ritorna false
. s
ritorna l'insieme (di tipo Set
,
creato ex novo) che contiene tutti gli insiemi generici che non sono
disgiunti da s
. Collection
)
di oggetti di un qualsiasi tipo che è un sottotipo di insiemi generici
con elementi di tipo E
, rimuove dall'insieme ogni insieme
generico s
che ha intersezione non vuota con qualche
insieme della collezione. Set
,
creato ex novo, l'unione degli elementi
di tutti gli insiemi generici presenti nell'insieme. Iterable
per iterare sugli insiemi generici
dell'insieme. import java.util.*;
public class Test {
public static void main(String[] args) {
Object oggetto = 'a';
char c1, c2;
c1 = (char)oggetto;
c2 = (Character)oggetto;
Double[] valori = new Double[15];
Number[] numeri = valori;
numeri[0] = new Integer(5);
Set<Integer> insieme = new HashSet<Integer>();
for (int i = 0 ; i < 10 ; i++) insieme.add(i);
for (Integer k : insieme)
if (k % 2 == 0)
insieme.remove(k);
valori[1] += insieme.size();
}
}
public interface Seq<V> {Ad esempio, una classe che rappresenta sequenze di interi potrebbe chiamarsi
V get(int i); //Ritorna l'i-esimo valore della sequenza (la numerazione inizia da 0)
int length(); //Ritorna la lunghezza della sequenza
}
IntSeq
e
implementare Seq<Integer>
.
Si vuole definire una classe generica per gestire insiemi prefix-free
di sequenze con valori dello stesso tipo. Un insieme è prefix-free se
non ci sono nell'insieme due sequenze che sono l'una il prefisso
dell'altra
(una sequenza s1
è un prefisso di s2
se per
ogni i = 0,1,...,s1.length()-1
, s1.get(i)
è
un valore uguale al valore s2.get(i)
).
La classe ha un solo parametro di tipo V
che rappresenta
il tipo dei valori delle sequenze. La classe deve definire i seguenti
costruttori e metodi.
true
.
Altrimenti ritorna false
. i
e un
valore v
(di tipo V
) ritorna l'insieme (di
tipo Set
, creato ex novo) di tutte le sequenze che in
posizione i
hanno valore v
. Collection
)
di oggetti di un tipo che è un sottotipo di sequenze di valori di tipo V
,
rimuove dall'insieme ogni sequenza s
che o è un prefisso
di una sequenza della collezione o c'è una sequenza della collezione
che è
un prefisso di s
. Iterable
per iterare sulle sequenze
dell'insieme. null
. Scrivere anche una versione non
generica del
metodo
usando il tipo Object
. Esibire un esempio di invocazione
dei due metodi che evidenzia il vantaggio offerto dalla versione
generica. Map<T,Integer>
, che contiene per ogni
valore distinto
dell'array il numero di occorrenze di quel valore. Esempi:
ARRAY DI INPUT MAPPA DI OUTPUT
["A", "BB", "C", "BB", "A"] {("A", 2), ("BB", 2), ("C", 1)}
[8, 7, 9, 7, 7, null, 9] {(8, 1), (7, 3), (9, 2), (null, 1)}
import java.util.*;
public class Test {
public static void main(String[] args) {
List<Long> list = new ArrayList<Long>();
for (long i = 0 ; i < 10 ; i++) list.add(i);
for (Long k : list)
if (k < 100)
list.remove(k);
Float[] vals = new Float[10];
Number[] nums = vals;
nums[0] = new Integer(7);
vals[1] += list.size();
Object o = 23;
int a = (int)o;
int b = (Integer)o;
}
}
T
è
coinvolto in una relazione di dipendenza se il tipo stesso o un suo
supertipo S
implementa la seguente interfaccia
generica:
public interface DependingOn<S> {Il metodo dell'interfaccia determina solamente la relazione di dipendenza diretta che, in generale, non è transitiva. Invece, una relazione di dipendenza è per sua natura transitiva, cioè, se
boolean directDependsOn(S x); //Ritorna true se questo oggetto dipende direttamente da x o se è uguale a x
}
x
dipende da y
e y
dipende da z
,
allora x
dipende anche da z
. Definire una
classe per gestire insiemi di oggetti coinvolti in una relazione di
dipendenza (tramite l'interfaccia DependingOn
) che
permette di ottenere informazioni sulle dipendenze tra gli oggetti
dell'insieme che sono conseguenza della transitività. La classe ha un
unico parametro di tipo T
che rappresenta
il tipo degli oggetti coinvolti in una relazione di dipendenza.
La classe ha un costruttore che crea un insieme vuoto (potrebbe anche
essere quello di default). Poi, deve definire i seguenti metodi.
x
solo se
non
ci sono
altri elementi
nell'insieme che dipendono da x
. Ritorna true
se effettua la rimozione,
altrimenti false
. x
di
tipo T
e ritorna il sottoinsieme (di tipo Set
, creato ex novo)
degli elementi
dell'insieme che sono direttamente dipendenti da x
.coll
(di
tipo Collection
con parametro di tipo tale da garantire
la massima flessibilità) e ritorna
il sottoinsieme degli elementi dell'insieme che sono direttamente
dipendenti da qualche elemento della collezione coll
.x
di
tipo T
e ritorna il sottoinsieme degli elementi dell'insieme che sono
transitivamente dipendenti da x
. Un elemento z
è transitivamente dipendente
da x
se esiste un elemento y
tale che z
dipende direttamente da y
e y
dipende (transitivamente)
da x
.Iterable
per
iterare sugli elementi dell'insieme.INPUT OUTPUT
{"B", "AB", "A", "B"} ("B", 2)
{2, 13, 2, 1, 13, 13} (13, 3)