Come comunicare che l'ordine di inserzione conta in una mappa?


24

Sto recuperando un set di tuple dal database e lo inserisco in una mappa. La query del database è costosa.

Non esiste un ordinamento naturale ovvio degli elementi nella mappa, ma l'ordine di inserimento è comunque importante. L'ordinamento della mappa sarebbe un'operazione pesante, quindi voglio evitare di farlo, dato che il risultato della query è già ordinato nel modo desiderato. Pertanto, memorizzo solo il risultato della query in a LinkedHashMape restituisco la mappa da un metodo DAO:

public LinkedHashMap<Key, Value> fetchData()

Ho un metodo processDatache dovrebbe eseguire alcune elaborazioni sulla mappa: la modifica di alcuni valori, l'aggiunta di alcune nuove chiavi / valori. È definito come

public void processData(LinkedHashMap<Key, Value> data) {...}

Tuttavia, diversi linter (sonar ecc.) Lamentano che il tipo di "dati" dovrebbe essere un'interfaccia come "Mappa" anziché l'implementazione "LinkedHashMap" ( calamaro S1319 ).
Quindi sostanzialmente sta dicendo che avrei dovuto

public void processData(Map<Key, Value> data) {...}

Ma voglio che la firma del metodo dica che l' ordine delle mappe è importante - è importante per l'algoritmo processData- in modo che il mio metodo non venga passato da qualsiasi mappa casuale.

Non voglio usarlo SortedMap, perché (dal javadoc dijava.util.SortedMap ) "è ordinato secondo l' ordinamento naturale delle sue chiavi, o da un comparatore in genere fornito al momento della creazione della mappa ordinata".

Le mie chiavi non hanno un ordinamento naturale e la creazione di un comparatore per non fare nulla sembra dettagliata.

E vorrei ancora che fosse una mappa, di cui approfittare putper evitare chiavi duplicate ecc. In caso contrario, dataavrebbe potuto essere un List<Map.Entry<Key, Value>>.

Quindi, come posso dire che il mio metodo vuole una mappa già ordinata ? Purtroppo, non esiste java.util.LinkedMapun'interfaccia, o l'avrei usata.

Risposte:


56

Quindi usa LinkedHashMap.

, Mapquando possibile è necessario utilizzare un'implementazione specifica e , , questa è la migliore pratica.

Detto questo, questa è una situazione stranamente specifica in cui l'implementazione della Maprealtà conta. Questo non sarà vero per il 99,9% dei casi nel tuo codice quando usi Map, eppure eccoti qui, in questa situazione dello 0.1%. Il sonar non può saperlo e quindi Sonar ti dice semplicemente di evitare di utilizzare l'implementazione specifica perché sarebbe corretto nella maggior parte dei casi.

Direi che se riesci a fare un caso per usare un'implementazione specifica, non provare a mettere il rossetto su un maiale. Hai bisogno di un LinkedHashMap, non di un Map.

Detto questo, se sei nuovo nella programmazione e incappare in questa risposta, non pensare che ciò ti permetta di andare contro le migliori pratiche perché non lo è. Ma quando sostituire un'implementazione con un'altra non è accettabile, l'unica cosa che puoi fare è usare quella specifica implementazione ed essere dannato per Sonar.


1
Approccio pragmatico, che mi piace.
Vidar S. Ramdal,

20
Concordo quasi completamente con la risposta. Direi solo che non sei dannato per il sonar. Puoi sempre configurarlo per ignorare quel particolare errore / avviso. Vedere stackoverflow.com/questions/10971968/...
Vladimir Stokic

11
if you are new to programming and stumble upon this answer, don't think this allows you to go against best practice because it doesn't.- Un buon consiglio, se esistesse qualcosa come "best practice". Un consiglio migliore: impara come prendere le giuste decisioni. Segui la pratica se ha senso, ma lascia che strumenti e autorità guidino il tuo processo di pensiero, non dettarlo.
Robert Harvey,

13
Nota: quando il sonar ti segnala qualcosa, puoi chiuderlo come "non sarà risolto" e lasciare una nota come perché non lo farai. Come tale, non solo il sonar smetterà di disturbarti, ma avrai un tracciante del perché lo hai fatto.
Walfrat,

2
Penso che l'aspetto che rende questa un'eccezione al principio generale sia che LinkedHashMap abbia un contratto specifico per tale implementazione e non espresso in alcuna interfaccia. Questo non è il solito caso. Quindi l'unico modo per esprimere la dipendenza da quel contratto è usare il tipo di implementazione.
Dana,

21

Stai combattendo tre cose:

Il primo è la libreria di contenitori Java. Nulla nella sua tassonomia ti dà un modo per determinare se la classe scorre o meno in un ordine prevedibile. Non esiste IteratesInInsertedOrderMapun'interfaccia che potrebbe essere implementata da LinkedHashMap, il che rende impossibile il controllo del tipo (e l'uso di implementazioni alternative che si comportano allo stesso modo). Questo è probabilmente di progettazione, perché lo spirito è che dovresti davvero essere in grado di gestire oggetti che si comportano come l'astratto Map.

La seconda è la convinzione che ciò che dice il tuo linter debba essere trattato come un vangelo e che ignorare tutto ciò che dice è un male. Contrariamente a ciò che passa per la buona pratica in questi giorni, gli avvisi di linter non dovrebbero essere ostacoli al buon codice. Sono spunti per ragionare sul codice che hai scritto e usare la tua esperienza e giudizio per determinare se l'avviso è giustificato o meno. Avvertimenti ingiustificati sono il motivo per cui quasi tutti gli strumenti di analisi statica forniscono un meccanismo per dire che hai esaminato il codice, pensi che ciò che stai facendo sia a posto e che non dovrebbero lamentarsene in futuro.

Terzo, e questa è probabilmente la carne, LinkedHashMappotrebbe essere lo strumento sbagliato per il lavoro. Le mappe sono pensate per l'accesso casuale, non ordinato. Se processData()scorre semplicemente i record in ordine e non è necessario trovare altri record per chiave, stai forzando un'implementazione specifica di Mapfare il lavoro di a List. D'altra parte, se hai bisogno di entrambi, LinkedHashMapè lo strumento giusto perché è noto per fare quello che vuoi e sei più che giustificato nel richiederlo.


2
"LinkedHashMap potrebbe essere lo strumento sbagliato per il lavoro". Sì forse. Quando dico che ne ho bisogno OrderedMap, potrei anche dire UniqueList. Finché è una sorta di raccolta con un ordine di iterazione definito, che sovrascrive i duplicati sull'inserto.
Vidar S. Ramdal,

2
@ VidarS.Ramdal La query del database sarebbe il luogo ideale per eliminare i duplicati. Se il database non è in grado di farlo, è sempre possibile conservare temporaneamente Setsolo le chiavi durante la creazione dell'elenco come modo per individuarle.
Blrfl,

Oh, vedo che ho causato confusione. Sì, il risultato della query del database non contiene duplicati. Ma processDatamodifica la mappa, sostituendo alcuni valori, introducendo alcune nuove chiavi / valori. Quindi processDatapotrebbe introdurre duplicati se operasse su qualcosa di diverso da a Map.
Vidar S. Ramdal,

7
@ VidarS.Ramdal: Sembra che tu debba scrivere il tuo UniqueList(o OrderedUniqueList) e usarlo. È abbastanza semplice e rende più chiaro l'uso previsto.
TMN

2
@TMN Sì, ho iniziato a pensare in quella direzione. Se vuoi pubblicare il tuo suggerimento come risposta, otterrà sicuramente il mio voto.
Vidar S. Ramdal,

15

Se tutto ciò che stai ottenendo LinkedHashMapè la possibilità di sovrascrivere i duplicati, ma lo stai davvero utilizzando come un List, quindi suggerirei che è meglio comunicare tale utilizzo con la tua Listimplementazione personalizzata . Puoi basarlo su una classe di raccolte Java esistente e semplicemente ignorare qualsiasi metodo adde removeper aggiornare il tuo archivio di backup e tenere traccia della chiave per garantire l'univocità. Dare a questo un nome distintivo come ProcessingListchiarirà che gli argomenti presentati al tuo processDatametodo devono essere gestiti in un modo particolare.


5
Questa può essere comunque una buona idea. Diamine, puoi anche avere un file di una riga che crea ProcessingListcome alias per LinkedHashMap: puoi sempre decidere di sostituirlo con qualcos'altro in seguito, purché mantenga intatta l'interfaccia pubblica.
CompuChip

11

Ti sento dire "Ho una parte del mio sistema che produce una LinkedHashMap e in un'altra parte del mio sistema ho bisogno di accettare solo gli oggetti LinkedHashMap prodotti dalla prima parte, poiché quelli prodotti da altri processi hanno vinto" non funziona correttamente. "

Questo mi fa pensare che il problema qui sia in realtà che stai cercando di utilizzare LinkedHashMap poiché si adatta principalmente ai dati che stai cercando, ma in realtà non può essere sostituito con nessun'altra istanza rispetto a quelle che crei. Quello che realmente vuoi fare è creare la tua interfaccia / classe che è ciò che crea la tua prima parte e la seconda parte consuma. Può racchiudere la "reale" LinkedHashMap e fornire un getter Map o implementare l'interfaccia Map.

Questo è un po 'diverso dalla risposta di CandiedOrange, in quanto consiglierei di incapsulare la vera Mappa (e delegare le chiamate ad essa secondo necessità) piuttosto che estenderla. A volte è una di quelle guerre sante di stile, ma mi sembra sicuramente che non sia "Una mappa con alcune cose aggiuntive", è "La mia valigia di utili informazioni sullo stato, che posso rappresentare internamente con una mappa".

Se avessi avuto due variabili che avresti dovuto passare in questo modo, probabilmente avresti creato una classe senza pensarci molto. Ma a volte è utile avere una classe anche se è solo una variabile membro, solo perché è logicamente la stessa cosa, non un "valore" ma "il risultato della mia operazione con cui devo fare le cose in seguito".


Mi piace questo modo di pensare - Io ci sono stato :) MyBagOfUsefulInformationavrebbe bisogno di un metodo (o costruttore) per popolarlo: MyBagOfUsefulInformation.populate(SomeType data). Ma datadovrebbe essere il risultato della query ordinata. Quindi quale sarebbe SomeType, se no LinkedHashMap? Non sono sicuro di riuscire a rompere questo Catch 22.
Vidar S. Ramdal

Perché non può MyBagOfUsefulInformationessere creato dal DAO o da qualunque cosa generi i dati nel tuo sistema? Perché è necessario esporre la mappa sottostante al resto del codice al di fuori del produttore e del consumatore del Bag?

A seconda dell'architettura, potresti essere in grado di utilizzare un costruttore privato / protetto / solo pacchetto per imporre che l'oggetto può essere creato solo dal produttore che desideri. Oppure potresti aver bisogno di farlo come una convenzione, che può essere creato solo dalla "fabbrica" ​​giusta.

Sì, ho finito per fare qualcosa di simile, passando MyBagOfUsefulInformationcome parametro al metodo DAO: softwareengineering.stackexchange.com/a/360079/52573
Vidar S. Ramdal

4

LinkedHashMap è l'unica mappa java che ha la funzione di ordine di inserimento che stai cercando. Quindi scartare il principio di inversione di dipendenza è allettante e forse anche pratico. Prima però, considera cosa ci vorrebbe per seguirlo. Ecco cosa ti chiederebbe SOLID .

Nota: sostituire il nome Ramdalcon un nome descrittivo che comunica che il consumatore di questa interfaccia è il proprietario di questa interfaccia. Il che lo rende l'autorità che decide se l'ordine di inserimento è importante. Se lo chiami InsertionOrderMap, hai davvero perso il punto.

public interface Ramdal {
    //ISP asks for just the methods that processData() actually uses.
    ...
}

public class RamdalLinkedHashMap extends LinkedHashMap implements Ramdal{} 

Ramdal<Key, Value> ramdal = new RamdalLinkedHashMap<>();

ramdal.put(key1, value1);
ramdal.put(key2, value2);

processData(ramdal);

È un grande design in primo piano? Forse dipende da quanto probabilmente pensi che avrai mai bisogno di un'implementazione oltre LinkedHashMap. Ma se non stai seguendo DIP solo perché sarebbe un grande dolore, non penso che la piastra della caldaia sia più dolorosa di questa. Questo è il modello che uso quando desidero che il codice intoccabile abbia implementato un'interfaccia che non ha. La parte più dolorosa è davvero pensare a buoni nomi.


2
Mi piace la denominazione!
Vidar S. Ramdal,

1

Grazie per tanti buoni suggerimenti e spunti di riflessione.

Ho finito per estendere la creazione di una nuova classe di mappe, creando processDataun metodo di istanza:

class DataMap extends LinkedHashMap<Key, Value> {

   processData();

}

Quindi ho riformattato il metodo DAO in modo che non restituisca una mappa, ma invece prenda una targetmappa come parametro:

public void fetchData(Map<Key, Value> target) {
  ...
  // for each result row
  target.put(key, value);
}

Quindi popolare DataMaped elaborare i dati ora è un processo in due fasi, il che va bene, poiché ci sono alcune altre variabili che fanno parte dell'algoritmo, che proviene da altri luoghi.

public DataMap fetchDataMap() {
  var dataMap = new DataMap();
  dao.fetchData(dataMap);
  return dataMap;
}

Ciò consente alla mia implementazione di Map di controllare il modo in cui le voci vengono inserite al suo interno e nascondere i requisiti di ordinazione - ora è un dettaglio di implementazione di DataMap.


0

Se vuoi comunicare che la struttura di dati che hai usato è lì per un motivo, aggiungi un commento sopra la firma del metodo. Se in futuro un altro sviluppatore si imbatte in questa riga di codice e nota un avviso dello strumento, potrebbe anche notare il commento e astenersi dal "risolvere" il problema. Se non ci sono commenti, nulla impedisce loro di modificare la firma.

Sopprimere gli avvisi è inferiore a commentare secondo me, perché la soppressione stessa non indica il motivo per cui l'avvertimento è stato soppresso. Anche una combinazione di soppressione degli avvertimenti e commenti andrà bene.


0

Quindi, lasciami provare a capire il tuo contesto qui:

... l'ordine di inserimento è importante ... L'ordinamento della mappa sarebbe un'operazione pesante ...

... il risultato della query è già ordinato nel modo desiderato

Ora, quello che stai già facendo:

Sto recuperando un set di tuple dal database e lo inserisco in una mappa ...

Ed ecco il tuo codice attuale:

public void processData(LinkedHashMap<Key, Value> data) {...}

Il mio consiglio è di fare quanto segue:

  • Usa l' iniezione delle dipendenze e inietta un po 'di MyTupleRepository nel metodo di elaborazione (MyTupleRepository è un'interfaccia implementata da oggetti che recuperano i tuoi oggetti tuple, generalmente dal DB);
  • internamente al metodo di elaborazione, inserire i dati dal repository (aka DB, che già restituisce i dati ordinati) nella raccolta LinkedHashMap specifica, poiché si tratta di dettagli interni dell'algoritmo di elaborazione (perché dipende da come sono disposti i dati nella struttura dei dati );
  • Nota che questo è praticamente ciò che stai già facendo, ma in questo caso ciò avverrebbe nel metodo di elaborazione. Il tuo repository è istanziato da qualche altra parte (hai già una classe che restituisce dati, questo è il repository in questo esempio)

Esempio di codice

public interface MyTupleRepository {
    Collection<MyTuple> GetAll();
}

//Concrete implementation of data access object, that retrieves 
//your tuples from DB; this data is already ordered by the query
public class DbMyTupleRepository implements MyTupleRepository { }

//Injects some abstraction of repository into the processing method,
//but make it clear that some exception might be thrown if data is not
//arranged in some specific way you need
public void processData(MyTupleRepository tupleRepo) throws DataNotOrderedException {

    LinkedHashMap<Key, Value> data = new LinkedHashMap<Key, Value>();

    //Represents the query to DB, that already returns ordered data
    Collection<MyTuple> myTuples = tupleRepo.GetAll();

    //Optional: this would throw some exception if data is not ordered 
    Validate(myTuples);

    for (MyTupleData t : myTuples) {
        data.put(t.key, t.value);
    }

    //Perform the processing using LinkedHashMap...
    ...
}

Immagino che questo eliminerebbe l'avviso Sonar e specifichi anche nel layout specifico della firma dei dati richiesti dal metodo di elaborazione.


Hmm, ma come sarebbe istanziato il repository? Questo non MyTupleRepository
sposterebbe

Penso che incontrerò lo stesso problema della risposta di Peter Cooper .
Vidar S. Ramdal,

Il mio suggerimento riguarda l'applicazione del principio di iniezione di dipendenza; in questo esempio; MyTupleRepository è un'interfaccia che definisce la capacità di recuperare le tuple che hai citato (che interroga DB). Qui, si inserisce questo oggetto nel metodo di elaborazione. Hai già qualche classe che restituisce i dati; questo lo astrae solo in un'interfaccia e si inietta l'oggetto nel metodo 'processData', che utilizza internamente LinkedHashMap perché è intrinsecamente parte dell'elaborazione.
Emerson Cardoso,

Ho modificato la mia risposta, cercando di essere più chiaro su ciò che sto suggerendo.
Emerson Cardoso,

-1

Questa domanda è in realtà una serie di problemi con il modello di dati raggruppati in uno. Devi iniziare a districarli, uno alla volta. Soluzioni più naturali e intuitive cadranno mentre provi a semplificare ogni pezzo del puzzle.

Problema 1: non è possibile dipendere dall'ordine DB

Le descrizioni dell'ordinamento dei dati non sono chiare.

  • Il potenziale problema più grande è che non stai specificando un ordinamento esplicito nel tuo database, tramite una ORDER BYclausola. Se non lo sei perché sembra troppo costoso, il tuo programma ha un bug . I database possono restituire risultati in qualsiasi ordine se non ne specifichi uno; non puoi dipendere dal fatto che i dati vengano restituiti casualmente nell'ordine solo perché hai eseguito la query più volte e sembra così. L'ordine potrebbe cambiare perché le righe vengono riorganizzate sul disco o alcune vengono eliminate e ne vengono sostituite di nuove o viene aggiunto un indice. È necessario specificare una ORDER BYclausola di qualche tipo. La velocità è inutile senza correttezza.
  • Inoltre, non è chiaro cosa si intende per ordine di inserzione importante. Se si parla del database stesso, è necessario disporre di una colonna che effettivamente tiene traccia di questo, e deve essere incluso nella ORDER BYclausola. Altrimenti, hai dei bug. Se tale colonna non esiste ancora, è necessario aggiungerne una. Le opzioni tipiche per colonne come questa sarebbero una colonna data / ora di inserimento o una chiave auto-incrementante. La chiave auto-incrementante è più affidabile.

Problema 2: rendere efficiente l'ordinamento in memoria

Una volta che hai la certezza che è garantito per essere la restituzione di dati nell'ordine che ci si aspetta, è possibile sfruttare questo fatto per fare in memoria comando ordina molto più efficiente. Basta aggiungere una colonna row_number()odense_rank() (o equivalente del database) al set di risultati della query. Ora ogni riga ha un indice che ti darà un'indicazione diretta di ciò che dovrebbe essere l'ordine, e puoi ordinarlo banalmente in memoria. Assicurati solo di dare all'indice un nome significativo (come sortedBySomethingIndex).

Viola. Ora non è più necessario dipendere dall'ordine del set di risultati del database.

Problema 3: hai anche bisogno di eseguire questa elaborazione nel codice?

SQL è in realtà molto potente. È un fantastico linguaggio dichiarativo che ti consente di fare molte trasformazioni e aggregazioni sui tuoi dati. Oggigiorno la maggior parte dei DB supporta anche operazioni a file incrociate. Si chiamano funzioni finestra o analitiche:

Hai anche bisogno di mettere i tuoi dati in memoria in questo modo? O potresti fare tutto il lavoro nella query SQL usando le funzioni della finestra? Se riesci a fare tutto (o forse anche solo una parte significativa) del lavoro nel DB, fantastico! Il tuo problema con il codice scompare (o diventa molto più semplice)!

Problema 4: stai facendo cosa data?

Supponendo che non puoi fare tutto nel DB, fammi capire bene. Stai prendendo i dati come mappa (che è chiave per cose che non vuoi ordinare), quindi stai iterando su di esso in ordine di inserimento , e modificando la mappa in atto sostituendo il valore di alcune chiavi e aggiungendo nuovi?

Mi dispiace, ma che diamine?

I chiamanti non dovrebbero preoccuparsi di tutto questo . Il sistema che hai creato è estremamente fragile. Ci vuole solo un errore stupido (forse anche fatto da te, come abbiamo fatto tutti) per fare un piccolo cambiamento sbagliato e il tutto collassa come un mazzo di carte.

Ecco forse un'idea migliore:

  • Chiedi alla tua funzione di accettare a List.
  • Esistono un paio di modi in cui è possibile gestire il problema di ordinazione.
    1. Applica Fail Fast. Generare un errore se l'elenco non è nell'ordine richiesto dalla funzione. (Nota: è possibile utilizzare l'indice di ordinamento dal Problema 2 per sapere se lo è.)
    2. Crea tu stesso una copia ordinata (usando nuovamente l'indice dal problema 2).
    3. Scopri un modo per costruire la mappa stessa in ordine.
  • Costruisci la mappa di cui hai bisogno internamente alla funzione, in modo che il chiamante non debba preoccuparsene.
  • Ora ripeti tutto ciò che hai in ordine di rappresentazione e fai quello che devi fare.
  • Restituisci la mappa o trasformala in un valore di ritorno appropriato

Una possibile variazione potrebbe essere quella di costruire una rappresentazione ordinata e quindi creare una mappa della chiave da indicizzare . Ciò ti consentirebbe di modificare la copia ordinata in atto, senza creare accidentalmente duplicati.

O forse questo ha più senso: sbarazzarsi del dataparametro e far processDataeffettivamente recuperare i propri dati. Puoi quindi documentare che lo stai facendo perché ha requisiti molto specifici sul modo in cui i dati vengono recuperati. In altre parole, rendere la funzione proprietaria dell'intero processo, non solo di un suo pezzo; le interdipendenze sono troppo forti per dividere la logica in blocchi più piccoli. (Cambia il nome della funzione nel processo.)

Forse questi non funzioneranno per la tua situazione. Non lo so senza tutti i dettagli del problema. Ma conosco un design fragile e confuso quando ne sento uno.

Sommario

Penso che il problema qui sia in definitiva che il diavolo sta nei dettagli. Quando inizio a incorrere in problemi come questo, di solito è perché ho una rappresentazione inappropriata dei miei dati per il problema che sto cercando di risolvere effettivamente. La soluzione migliore è trovare una rappresentazione migliore , e quindi il mio problema diventa semplice (forse non facile, ma diretto) da risolvere.

Trova qualcuno che capisca questo punto: il tuo compito è ridurre il tuo problema a un insieme di semplici e chiari. Quindi puoi creare un codice robusto e intuitivo. Parla con loro. Un buon codice e un buon design ti fanno pensare che qualsiasi idiota avrebbe potuto pensarli, perché sono semplici e diretti. Forse c'è uno sviluppatore senior che ha quella mentalità con cui puoi parlare.


"Che cosa vuoi dire che non esiste un ordine naturale ma l'ordine di inserimento è importante? Stai dicendo che è importante l'ordine in cui i dati sono stati inseriti nella tabella DB, ma non hai una colonna in grado di dirti in quale ordine sono state inserite le cose?" - la domanda afferma questo: "L'ordinamento della mappa sarebbe un'operazione pesante, quindi voglio evitare di farlo, dato che il risultato della query è già ordinato". Questo chiaramente significa che v'è un ordine definito calcolabile ai dati, perché altrimenti classificare sarebbe impossibile piuttosto pesante, ma questo ordine definito è diverso l'ordine naturale delle chiavi.
Jules

2
In altre parole, OP sta lavorando sui risultati di una query simile select key, value from table where ... order by othercolumne deve mantenere l'ordine nella loro elaborazione. L' ordine di inserimento a cui si riferiscono è l' ordine di inserimento nella loro mappa , definito dall'ordine utilizzato nella loro query, non dall'ordine di inserimento nel database . Ciò è chiarito dal loro uso di LinkedHashMap, che è una struttura di dati che ha le caratteristiche sia di una Mapche di una Listcoppia chiave-valore.
Jules

@Jules Pulirò un po 'quella sezione, grazie. (In realtà mi sono ricordato di averlo letto, ma quando stavo controllando le cose mentre scrivevo la domanda, non riuscivo a trovarlo. Lol. Ho anche preso le erbacce.) Ma la domanda non è chiara su cosa stanno facendo con il DB query e se hanno un ordinamento esplicito o meno. Dicono anche che "l'ordine di inserzione conta". Il punto è che anche se l'ordinamento è pesante, non puoi fare affidamento sul DB per ordinare magicamente le cose correttamente se non le dici esplicitamente. E se lo stai facendo nel DB, puoi usare un "indice" per renderlo efficiente nel codice.
jpmc26

* scrivendo la risposta (penso che dovrei andare a letto presto.)
jpmc26

Sì, @Jules ha ragione. V'è una order byclausola della query, ma non è banale ( non solo order by column), quindi voglio evitare reimplementare la selezione in Java. Sebbene SQL sia potente (e stiamo parlando di un database Oracle 11g qui), la natura processDatadell'algoritmo rende molto più semplice l'espressione in Java. E sì, "ordine di inserzione" significa " ordine di inserzione della mappa ", ovvero ordine dei risultati della query.
Vidar S. Ramdal,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.