Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 19

Discussione: Copia di un hashmap

  1. #1
    Utente di HTML.it
    Registrato dal
    Jan 2018
    Messaggi
    32

    Copia di un hashmap

    Ciao, ho un problema sulla copia di un hashmap. In pratica ho bisogno di creare una copia temporanea di un hashmap e accedere ai valori della copia eventualmente eliminandoli, senza toccare la hash originale. Il problema è che dopo aver creato la copia, se provo a fare un for each per scorrerla, viene lanciata un eccezione:
    Exception in thread "main" java.util.ConcurrentModificationException
    at java.util.HashMap$HashIterator.nextNode(Unknown Source)
    at java.util.HashMap$KeyIterator.next(Unknown Source)
    at impl.DirectedGraphAdjListImpl.topologicalSort(Dire ctedGraphAdjListImpl.java:420)
    at test.Prompt$Main.main(Prompt.java:193)
    La copia dell'hashmap l'ho creata come l'originale(ho fatto un ciclo e per ogni elemento faccio la put sulla copia), ma non capisco perchè mi dice Unknown Source. Se invece faccio una stampa della copia, me la stampa correttamente con i giusti valori al suo interno.

  2. #2
    Quote Originariamente inviata da Giuso Visualizza il messaggio
    La copia dell'hashmap l'ho creata come l'originale(ho fatto un ciclo e per ogni elemento faccio la put sulla copia)
    Non servirebbe fare così per la copia. HashMap ha un costruttore "di copia" apposito, bastava documentarsi:

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

    Quindi es.

    HashMap<String,String> orig = ......
    // ....
    HashMap<String,String> copia = new HashMap<>(orig);


    La documentazione javadoc ufficiale va letta ... e capita.

    Quote Originariamente inviata da Giuso Visualizza il messaggio
    e accedere ai valori della copia eventualmente eliminandoli, senza toccare la hash originale. Il problema è che dopo aver creato la copia, se provo a fare un for each per scorrerla, viene lanciata un eccezione:
    Exception in thread "main" java.util.ConcurrentModificationException
    Se usi il "for-each", NON puoi modificare in alcun modo la collezione all'interno del ciclo. L'iteratore delle collezioni standard ha il comportamento detto "fail-fast" e lancia ConcurrentModificationException se determina che la collezione nel frattempo (durante la iterazione) è stata modificata strutturalmente. Anche questo concetto è ben documentato nel javadoc.

    Se vuoi iterare E eliminare all'interno del ciclo, allora DEVI usare esplicitamente il Iterator ed usare il suo remove()
    Ultima modifica di andbin; 15-04-2018 a 14:18
    Andrea, www.andbin.net – Senior Java developer – SCJP 5 (91%) – SCWCD 5 (94%)

  3. #3
    Utente di HTML.it
    Registrato dal
    Jan 2018
    Messaggi
    32
    Ah è la remove() allora che mi dava problemi. Ma l'utilizzo di Iterator posso farlo senza dover implementare la sua interfaccia dato che queste strutture la implementano?

  4. #4
    Quote Originariamente inviata da Giuso Visualizza il messaggio
    Ah è la remove() allora che mi dava problemi.
    Il remove() della collezione, sì, NON può essere usato durante una iterazione fatta con Iterator (esplicito o "nascosto" dal for-each).
    Il remove() del Iterator no, non dà problemi.

    Quote Originariamente inviata da Giuso Visualizza il messaggio
    Ma l'utilizzo di Iterator posso farlo senza dover implementare la sua interfaccia dato che queste strutture la implementano?
    Non devi "implementare" proprio nulla. Devi solo tirare fuori l'oggetto Iterator dal Set delle chiavi o delle entry (a tua scelta) della mappa.


    P.S. se vuoi eliminare delle entry da una mappa basandoti su una condizione booleana di "predicato", da Java 8 puoi anche sfruttare il nuovo removeIf che i Set (e Collection in generale) possiede.
    Ultima modifica di andbin; 15-04-2018 a 15:23
    Andrea, www.andbin.net – Senior Java developer – SCJP 5 (91%) – SCWCD 5 (94%)

  5. #5
    Utente di HTML.it
    Registrato dal
    Jan 2018
    Messaggi
    32
    Ok quello l'ho risolto.
    Altra domanda: ho 2 metodi, nel primo creo un Integer i = new Integer(); e questo oggetto lo passo come parametro del secondo metodo. Nel secondo metodo faccio un decremento di i. Questo metodo che effettua il decremento viene invocato in un ciclo all'interno del primo metodo. Il problema è che se ad es. i=5 nel primo metodo, nel secondo metodo ho sempre i = 4, e non decrementa, cioè in pratica ogni volta che richiamo il metodo gli viene passato il valore originario ovvero 5. In java gli oggetti non sono passati per riferimento? Quindi se io faccio i--, la volta dopo dovrebbe valere 4, quindi un ulteriore i-- dovrebbe produrmi 3, o sbaglio?

  6. #6
    In Java il passaggio degli argomenti a costruttori/metodi è sempre per valore. Quando si tratta di oggetti, viene passata una COPIA del VALORE del reference. E in sostanza vuol dire che assegnare qualcos'altro ad un parametro NON cambia ciò che il chiamante ha in mano ed ha passato.

    Il tuo approccio pertanto è sbagliato.
    Andrea, www.andbin.net – Senior Java developer – SCJP 5 (91%) – SCWCD 5 (94%)

  7. #7
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    16,996
    Tra l'altro gli oggetti Integer (come tutti i wrapper dei primitivi) sono immutabili: non ne puoi modificare il valore interno (e l'auto-boxing, in questi casi, rischia di fregarti se non conosci bene questi aspetti).


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  8. #8
    Utente di HTML.it
    Registrato dal
    Jan 2018
    Messaggi
    32
    Avrei un'altra domanda. nella mia hashmap ho come chiavi degli oggetti e come valori liste di oggetti. Queste liste contengono anche valori che compaiono nelle chiavi, mi spiego meglio:
    1-> [2,3]
    2->[1,4] e così via...
    Come si può notare dall'esempio, ho la chiave 1, ma questo 1 compare anche come oggetto all'interno della lista della seconda chiave. Se io vado a modificare l'oggetto con valore 1 nella lista di chiave 2, vorrei che tale modifica si riperquotesse anche sulla chiave 1. Come potrei fare?

  9. #9
    Quote Originariamente inviata da Giuso Visualizza il messaggio
    vorrei che tale modifica si riperquotesse anche sulla chiave 1. Come potrei fare?
    Un oggetto usato come "chiave" in una mappa (specialmente quelle basate su hash-table come HashMap; ma anche TreeMap, per dire) NON dovrebbe cambiare stato.
    Se hai un oggetto "mutabile" di una tua classe che è già nella mappa come chiave e altrove avendo il riferimento gli cambi lo stato .... se questo stato è usato per la "uguaglianza" della chiave, allora "brutte" cose possono capitare ...
    Gli oggetti usati come chiavi dovrebbero essere immutabili.

    Quindi: o il tuo design/approccio è proprio sbagliato e insensato ..... oppure se un senso ce l'ha dovresti chiarire meglio motivazioni ed obiettivi.
    Andrea, www.andbin.net – Senior Java developer – SCJP 5 (91%) – SCWCD 5 (94%)

  10. #10
    Utente di HTML.it
    Registrato dal
    Jan 2018
    Messaggi
    32
    Questi oggetti hanno 3 campi, e quello che mi serve modificare è un solo campo. La chiave e un oggetto altrove non possono essere "uguali" cioè non ce un modo che la modifica su uno possa automaticamente modificare l'altro, giusto? Se ce un modo per far si che ciò avvenga, mi piacerebbe conoscerlo, perché è ciò che mi serve. Altrimenti se non posso modificare la chiave sono fregato....

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2018 vBulletin Solutions, Inc. All rights reserved.