Sto progettando una semplice GUI che consentirà a un utente di creare un percorso GPX facendo clic ripetutamente su un pannello mappa. Mi trovo di fronte a un dilemma progettuale su come rappresentare i nodi e il percorso. Questo costrutto può essere astratto come segue:
- l'utente fa clic su n volte sullo schermo in sequenza per creare una catena di n nodi
- dopo che una catena è stata completata, un utente può aggiungere altri nodi ad esso, selezionando i nodi nel mezzo (inserendo tra i nodi esistenti) o semplicemente aggiungendo automaticamente alla fine con il suo clic successivo
All'inizio ero determinato a utilizzare una classe di collezioni Java per rappresentare la catena, ma ci sono difficoltà inaspettate. Sulla superficie, questo sembrerebbe essere un perfetto esempio di LinkedList
, ma considera come segue. Se l'utente desidera inserire un nodo nel mezzo della catena, sceglie prima un nodo sullo schermo che desidera inserire prima un nuovo nodo. Se il nodo appartiene a una lista collegata, sarà necessario mantenere un riferimento alla sua lista che comprende (una pratica piuttosto insolita, direi), e anche allora dovremo ancora individuare il nodo nella lista prima di poter inserire . Quindi dobbiamo:
- trova il nodo (tempo lineare)
- inserisci il nuovo nodo (tempo costante)
O se provo la stessa cosa con un ArrayList
, si comporta anche al meglio nel tempo lineare.
- trova il nodo (tempo lineare)
- inserisci il nuovo nodo (tempo lineare)
Ma nessuno dei due casi sembra davvero desiderabile. Ho flirtato brevemente con l'idea di utilizzare un LinkedHashSet
, ma non consente l'inserimento nel mezzo dell'elenco collegato, né sembra fondamentalmente corretto utilizzare un'implementazione impostata per qualcosa di simile.
Quindi ecco cosa mi è venuto in mente:
class Node {
Node previous;
Node next;
Chain chain;
}
Un nodo mantiene solo un riferimento ai suoi nodi precedenti e successivi, così come la catena a cui appartiene (anche in questo caso quest'ultima parte sembra non convenzionale e forse addirittura dispendiosa per me, ma sono convinto che potrebbe essere necessario qui) .
class Chain {
Node first;
Node last;
}
La catena conosce solo il suo primo e ultimo nodo.
Ora, se un utente vuole inserire un nodo nel mezzo della catena? Seleziona il nodo, che aggiorna semplicemente il primo / ultimo riferimento di se stesso e dei suoi vicini. Se vuole aggiungere nodi alla fine di una catena? Seleziona semplicemente qualsiasi nodo sullo schermo (che è consapevole della catena a cui appartiene, e quindi di quale sia l'ultimo nodo di quella catena), e la catena inizia immediatamente ad aggiornare i riferimenti di collegamento per l'ultimo nodo e ogni nodo aggiunto dopo di essa, come oltre a mantenere aggiornato il proprio "ultimo" riferimento.
Volevo davvero usare una classe Collections, ma questo approccio mi sembra migliore. Ma mi piacerebbe qui pensieri / critiche da parte di programmatori più esperti. Grazie.