Ordinamento di una HashMap usando l'oggetto "valore" e non la chiave

di il
10 risposte

Ordinamento di una HashMap usando l'oggetto "valore" e non la chiave

Ciao.
un esercizio, trovato su interet chiede al punto
5. La stampa di tutti i contatti ordinata in ordine lessicografico

Premetto: trattasi di rubrica, con classe Contatto che ha telefono e nominativo.
L'hashMap è di tipo <String, Contatto> con chiave il telefono.

Ora, per risolvere il punto 5, ho fatto un loop sull'oggetto HashMap, e creato una TreeMap con metodo put mettendo prima il nominativo come chiave e poi l'oggetto Contatto.
L'oggetto istanza di TreeMap è già ordinato.

Si può fare con metodo putAll o in un modo più rapido?
Oppure, (per non sprecare memoria) si può ordinare una HashMap per un campo dell'oggetto contatto, magari con un Comparator?
Non so se riesco a spiegarmi, nella Mappa ho come chiave il telefono, ma ordino per il campo "nominativo" che si trova all'interno dell'oggetto Contatto passato come valore nella HashMap.

Si può fare?
Tagan

10 Risposte

  • Re: Ordinamento di una HashMap usando l'oggetto "valore" e non la chiave

    tagan ha scritto:


    Ora, per risolvere il punto 5, ho fatto un loop sull'oggetto HashMap, e creato una TreeMap con metodo put mettendo prima il nominativo come chiave e poi l'oggetto Contatto.
    L'oggetto istanza di TreeMap è già ordinato.

    Si può fare con metodo putAll o in un modo più rapido?
    Non servono loop, put/putAll. TreeMap ha già un bel costruttore:

    public TreeMap(Map<? extends K,? extends V> m)

    tagan ha scritto:


    si può ordinare una HashMap per un campo dell'oggetto contatto, magari con un Comparator?
    No non sì può ... in nessun modo. Non c'è alcun "aggancio" per farlo con HashMap.
  • Re: Ordinamento di una HashMap usando l'oggetto "valore" e non la chiave

    andbin ha scritto:


    Non servono loop, put/putAll. TreeMap ha già un bel costruttore:

    public TreeMap(Map<? extends K,? extends V> m)
    Ma se uso il costruttore, non faccio altro che copiare la HashMap dentro una TreeMap, ma la chiave rimane il telefono, quando invece dobvrebbe diventare in nominativo.
    la mia copia era del tipo
    
    	public void orderPerNome() {
    		Map<String,Contatto> orderNome= new TreeMap<>();
    		for (Map.Entry<String, Contatto> entry:rubrica.entrySet()) {
    			orderNome.put(entry.getValue().getNominativo(), entry.getValue());
    		}
    		System.out.println(orderNome);
    	}
    
    se faccio
    Map<String,Contatto> orderNome= new TreeMap<>(rubrica);
    non cambia niente.
    dovrei fare Override del costruttore della TreeMap?
  • Re: Ordinamento di una HashMap usando l'oggetto "valore" e non la chiave

    tagan ha scritto:


    Ma se uso il costruttore, non faccio altro che copiare la HashMap dentro una TreeMap, ma la chiave rimane il telefono, quando invece dobvrebbe diventare in nominativo.
    Ah scusa, non avevo letto bene il dettaglio che vuoi mettere il nominativo invece che il telefono come chiave ....

    Lo puoi fare in maniera un po' compatta usando la Stream API partendo dal values() della mappa originale (dato che tutto dipende solo dal valore e non dalle chiavi originali).

    tagan ha scritto:


    dovrei fare Override del costruttore della TreeMap?
    No no, non c'entra niente l'override.
  • Re: Ordinamento di una HashMap usando l'oggetto "valore" e non la chiave

    andbin ha scritto:


    Ah scusa, non avevo letto bene il dettaglio che vuoi mettere il nominativo invece che il telefono come chiave ....

    Lo puoi fare in maniera un po' compatta usando la Stream API partendo dal values() della mappa originale (dato che tutto dipende solo dal valore e non dalle chiavi originali).
    Allora lo vedrò..... allo stream API ancora non ci sono arrivato. è tra gli ultimi capitoli.

    Il tutto era una mia curiosità perché il testo diceva, stampare i contatti in ordine alfabetico e non ordinare una Mappa.
    la prima cosa che ho fatto era creare una List e poi ordinarla con un Comparator.

    Poi mi sono chiesto come ordinare una Mappa e l'unica cosa che mi è venuta in mente era usare altri tipo di Mappe.

    Però.....altro problema. Ma una HashMap, non accetta chiavi duplicate. ma se come chiave avessi il cognome?
    come creare una struttura HashMap che accetti chiave duplicate?
  • Re: Ordinamento di una HashMap usando l'oggetto "valore" e non la chiave

    tagan ha scritto:


    Ma una HashMap, non accetta chiavi duplicate.
    Esatto.

    tagan ha scritto:


    ma se come chiave avessi il cognome?
    come creare una struttura HashMap che accetti chiave duplicate?
    La cosa più logica sarebbe trattare un Map<String,List<Contatto>>
    Così per "Rossi" ci possono essere associati più contatti (con appunto cognome Rossi).

    E sempre con la Stream API questo lo fai molto agevolmente ...
  • Re: Ordinamento di una HashMap usando l'oggetto "valore" e non la chiave

    andbin ha scritto:


    tagan ha scritto:


    Ma una HashMap, non accetta chiavi duplicate.
    Esatto.

    tagan ha scritto:


    ma se come chiave avessi il cognome?
    come creare una struttura HashMap che accetti chiave duplicate?
    La cosa più logica sarebbe trattare un Map<String,List<Contatto>>
    Così per "Rossi" ci possono essere associati più contatti (con appunto cognome Rossi).

    E sempre con la Stream API questo lo fai molto agevolmente ...
    Perfetto.
    e se io volessi usare una struttura con doppia chiave? tipo "marca"-"modello" ..... potrei fare una HashMap<HashMap<String, String>, List<Prodotto>>
    codi avrei come chiave una mappa che mi identifica marca e modello di unas serie di oggetti,
    esempio Key= Fiat,Panda e come valori per qusta chiave tutti veicoli Panda con colore, allestimento, alimentazione, cilindrata ecc.ecc.

    che scommetto si farà in modo semplicissimo con la Stream API ....pok mettiamoci a studiare.
  • Re: Ordinamento di una HashMap usando l'oggetto "valore" e non la chiave

    andbin ha scritto:


    La cosa più logica sarebbe trattare un Map<String,List<Contatto>>
    Anzi no, la doppia chiave dovrebbe essere questa HashMap<String (marca), HashMap<String (modello), List<Veicolo>>>

    Giusto?
  • Re: Ordinamento di una HashMap usando l'oggetto "valore" e non la chiave

    tagan ha scritto:


    Anzi no, la doppia chiave dovrebbe essere questa HashMap<String (marca), HashMap<String (modello), List<Veicolo>>>
    Scusa ma prima parlavi di "contatti" .... ora di "veicoli"? Mi sfugge ....

    Comunque sì, quest'ultima parametrizzazione ha senso. Solo che: a fronte di una marca/modello, quanti veicoli ti aspetti? Dipende da cosa rappresenta la classe Veicolo. Solo il modello come concetto? O una automobile concreta di quel modello?
    Per dire: se in Veicolo hai la targa, allora è certamente una automobile "reale", quindi una lista di veicoli ha senso per uno stesso nome di modello.
  • Re: Ordinamento di una HashMap usando l'oggetto "valore" e non la chiave

    andbin ha scritto:


    tagan ha scritto:


    Anzi no, la doppia chiave dovrebbe essere questa HashMap<String (marca), HashMap<String (modello), List<Veicolo>>>
    Scusa ma prima parlavi di "contatti" .... ora di "veicoli"? Mi sfugge ....

    Comunque sì, quest'ultima parametrizzazione ha senso. Solo che: a fronte di una marca/modello, quanti veicoli ti aspetti? Dipende da cosa rappresenta la classe Veicolo. Solo il modello come concetto? O una automobile concreta di quel modello?
    Per dire: se in Veicolo hai la targa, allora è certamente una automobile "reale", quindi una lista di veicoli ha senso per uno stesso nome di modello.
    Era un esempio.....non mi veniva niente con "Contatti"
    però diciamo che ad un concessionario serve un programma e vende sia auto nuove che usato.
    Serve appunto ....molto banalmente......
    una marca (prima chiave) es. Fiat
    poi un modello (seconda chiave) es. Panda
    poi una lista di modelli che sono veicoli concreti (omettendo classi astratte e bla bla bla).... avrò attributi come targa, km percorsi, allestimento, colore
    quindi se vogliamo "vederlo" come struttura (chiavi String):
    
    HashMap("Fiat"   ,(HashMap("Panda")  ,Lista [ veicolo1, veicolo2, veicolo3 ] ))
    HashMap(         ,(HashMap("Punto")  ,Lista [ veicolo4, veicolo5 ] ))
    HashMap("Renault",(HashMap("Clio")   ,Lista [ veicolo6, veicolo7, veicolo8 ] ))
    HashMap(         ,(HashMap("Captur") ,Lista [ veicolo9 ] ))
    
    giusto?
    Se vogliamo dargli una parvenza grafica.

    In questo modo se arriva una nuova Panda, dovrò solo estrarre la LIST e aggiornarla con un ADD, perché il metodo PUT per Fiat e Panda non farà altro che sovrascrivere per le stesse chiavi, la nuova Lista

    Ma dovrebbe funzionare..... va pensato bene, almeno per quanto mi riguarda, la funzione che estrae la LIST, dovrà
    - cercare la prima chiave nella prima HashMap,
    - poi cercare la seconda chiave nei VALORI di quest'ultima, che non sono altro che la seconda HashMap annidata
    - una volta trovata, estrarre la LIST,
    - poi operarci sopra con una ADD
    - poi fare una put della HashMap annidata per seconda chiave in modo da aggiornare la LIST nella struttura
    - infine ultima put della prima chiave e avere tutto allineato.

    Beh.....non è banale!
    fare
  • Re: Ordinamento di una HashMap usando l'oggetto "valore" e non la chiave

    tagan ha scritto:


    - poi fare una put della HashMap annidata per seconda chiave in modo da aggiornare la LIST nella struttura
    Se hai estratto la lista per farci add, NON serve fare un put. Non stai cambiando l'associazione nella mappa .... stai solo modificando l'oggetto lista.

    tagan ha scritto:


    - infine ultima put della prima chiave e avere tutto allineato.
    Neanche se la chiave l'avevi trovata.

    tagan ha scritto:


    Beh.....non è banale!
    E' più facile di quanto pensi ....
    public class InsiemeVeicoli {
        private Map<String, Map<String, List<Veicolo>>> mappaVeicoli = new HashMap<>();
    
        public void aggiungiVeicolo(Veicolo veicolo) {
            // ..........
        }
        
        // ... altro ...
    }
    Se "sai" usare il nuovo computeIfAbsent (da Java 8 ) delle Map, diventa una banalità, ovvero il contenuto di quel aggiungiVeicolo diventa esattamente di 3 righe di codice (provato poco fa) !
    Se non sai/puoi usare computeIfAbsent è solo un pelino più lungo.
Devi accedere o registrarti per scrivere nel forum
10 risposte