Richiesta di aiuto per capire questo metodo :

di il
16 risposte

16 Risposte - Pagina 2

  • Re: Richiesta di aiuto per capire questo metodo :

    FabioJ ha scritto:


    Vorrei provare a fare qualche esercizio provando ad utilizzare proprio l'estensione <? extends ...
    Fai un metodo (statico) es. kvJoin che riceve due List e restituisce una Map. La nuova mappa (puoi istanziare un HashMap) avrà come chiavi gli oggetti della prima lista e come valori associati (tra le stesse posizioni) gli oggetti della seconda lista.

    Deve essere possibile poi usarla come per es.:
    List<String> strings = Arrays.asList("one", "two");
    List<Integer> numbers = Arrays.asList(1, 2);
    
    Map<Object,Object> map = kvJoin(strings, numbers);
    Per ottenere una mappa con associazioni: "one" ---> 1 / "two" ---> 2

    Dovrai usare gli ? extends e ti dico subito che per iterare in "parallelo" sulle due liste conviene usare direttamente gli Iterator (così fai pratica pure su questi ).
  • Re: Richiesta di aiuto per capire questo metodo :

    Un esercizio classico è quello di calcolare l'unione di due insiemi.
    L'unione di due insiemi A e B è un nuovo insieme che contiene tutti gli elementi di A e tutti gli elementi di B.
    Se volessi scrivere un metodo che calcola l'insieme unione a partire da due insiemi puoi farlo attraverso il metodo
    public static <T> Set<T> union(Set<? extends T> a, Set<? extends T> b)
    Infatti se supponi che T sia Number, il set a potrebbe essere un Set<Integer> e b un Set<Double>, o viceversa; o entrambi possono essere Set<Integer> o Set<Double> o Set<Long>; o addirittura uno dei due o entrambi possono essere Set<Number>.
    Come posso utilizzare l'estensione <? extends ...?? potrei aggiungere alle lettere anche dei numeri ..
    Tipo TreeSet<E extends .....qualcosa ??
    String e Number hanno come antenato comune soltanto Object (a parte l'interfaccia Serializable) quindi l'unica soluzione è utilizzare un TreeSet<Object> o un Treeset<?> [*] ma in questo caso puoi inserire qualsiasi oggetto.

    Inoltre nel codice che hai postato sarebbe comunque un errore utilizzare <? extends ...> per il TreeSet parola, poichè poco dopo stai utilizzando il metodo addAll() che, come ti è stato detto, quando si usa <? extends...> non è possibile andare a modificare la collezione.

    Un altro esempio potrebbe essere un metodo che rimuove e restituisce il primo elemento da un buffer produttore.
    public static <T> T get(List<? extends T> producer) {
        if(producer.isEmpty()) return null;
        T elem=producer.remove(0);
        return elem;
    }
    Non a caso ho utlizzato il nome producer. Infatti esiste la seguente regola mnemonica: PECS (Producer Extends Consumer Super).
    Infatti quando si hanno dei produttori questi devono solo fornire, produrre appunto, elementi. Non devono immagazzinare, prendere in input nulla. E' lecito quindi usare <? extends...>. Invece se si usano dei consumatori, questi avranno la necessità di usare, consumare appunto, dei dati, magari immagazzinarli anche, in questa situazione si usa <? super...>.
    Se invece hai necessità sia di esporre dei dati, sia di immagazzinarli, probabilmente i wildcard sono la scelta sbagliata.

    [*]La differenza tra TreeSet<Object> e TreeSet<?> sta nel fatto che il primo è un tipo parametrizzato che contiene Object, permette di essere acceduto sia in lettura che in scrittura, il secondo invece può essere scritto anche come TreeSet<? extends Object> che può contenere oggetti che siano sottotipi di Object o Object stesso, ma può essere acceduta solo in lettura.
Devi accedere o registrarti per scrivere nel forum
16 risposte