Quando utilizzare un'interfaccia SortedMap?

2

La regola della programmazione è quella di utilizzare l'interfaccia più generale possibile. Ma la differenza tra Map e SortedMap è più sottile.

  • Si compilano allo stesso bytecode [credo]
  • Non viene fornita alcuna sicurezza aggiuntiva poiché il compilatore non è in grado di distinguere le differenze tra i due
  • SortedMap offre una condizione post supplementare non controllata dal compilatore, ovvero l'iteratore è ordinato

Preferirei il codice da scrivere

SortedMap<K, V> m = new TreeMap<>();

se si utilizza l'ordinamento. Ma non sono sicuro che questa regola abbia senso solo quando ci sono i controlli del compilatore.

Spero di ottenere una risposta un po 'rigorosa (ad esempio teorica del tipo), ma dal momento che questo riguarda una vera revisione del codice che sto facendo in questo momento, il modo in cui ciò si applica in pratica è sicuramente importante. Devo ancora trovare un esempio efficace del perché uno contenga, oltre a un rilievo di leggibilità che dipende circolarmente dai programmatori che seguono questa teoria.

    
posta djechlin 24.02.2015 - 02:21
fonte

2 risposte

4

Lo usi quando vuoi garantire che stai ricevendo dati ordinati in un parametro, o quando vuoi assicurare al consumatore del tuo metodo che stai fornendo dati ordinati.

Parametri

Se hai bisogno che i tuoi dati siano ordinati, chiedi che venga ordinato chiedendo l'interfaccia che corrisponde a ciò che ti serve. È probabilmente meno costoso per il metodo che ti invia i dati per dartelo ordinato (lo ottengono da un database e possono banalmente ordinarlo, ma invece lo hanno buttato in una HashMap perché questo è quello che tutti usano) di quanto lo sia per devi prendere Map e quindi aggiungerlo a SortedMap .

Se ne hai bisogno, ordina di ordinarlo.

Valori di ritorno

Questo è un po 'più controverso ... ci sono diverse scuole di pensiero qui.

Se produce dati ordinati secondo la natura del tuo metodo e non hai un motivo non , torna indietro all'interfaccia che consente ai consumatori dei tuoi dati lavora con esso nella maggior parte dei modi senza dando loro un'implementazione concreta (che ti blocca).

Quel "che ti blocca" fa parte del controverso bit. Alcuni ritengono che dovresti restituire l'interfaccia meno restrittiva (più generale) quando possibile ( Map anziché SortedMap e Collection anziché Set o List ).

Ci tornerei con la cosa più utile per i consumatori.

Metterò qui l'avvertenza che se questo è qualcosa che sarà sempre ordinato, è una cosa ... se qualcuno potrebbe voler creare una sottoclasse più tardi e non averlo ordinato ... questa è un'altra storia. Pertanto, devi considerare questo come parte della progettazione per l'estensione . Se non verrà esteso mai otterrai una risposta da questa delibera ... se può essere estesa, c'è un'altra risposta possibile.

perché è un po 'sopra un disastro e la gente dice cose al riguardo nella revisione del codice?

Bene, principio di sostituzione di Liskov sottolinea che ciò renderebbe più difficile la sottoclasse più tardi. I parametri del metodo non possono essere rafforzati da un sottotipo e i valori restituiti non possono essere rilassati.

Restituendo un SortedMap non si può rendere una sottoclasse successiva della classe restituire un tipo più debole. Inoltre, se si decide di restituire un tipo più debole in un secondo momento per qualche motivo, si tratta di un importante refactoring (cambiando tutte le SortedMap disponibili su Maps e eventualmente modificando le chiamate che utilizzano tale interfaccia in codice che deve gestire il più debole tipo).

I tuoi interni

In realtà non importa ciò che stai facendo all'interno del tuo codice. Usa una mappa ordinata ogni volta che hai dati ordinati e vuoi ordinarli in ordine. Soprattutto se stai facendo put chiama su di esso in momenti diversi e vuoi che rimanga in ordine.

Ora, potresti essere tentato di utilizzare LinkedHashMap invece se ottieni tutti i dati ordinati in una volta sola, inseriscili nell'ordine ordinato, quindi esegui solo remove chiamate contro di essa se esegui qualche modifica. Non è sbagliato, e presenta alcuni vantaggi (ricerche O (1) piuttosto che ricerche O (log n)). Tuttavia, è piuttosto inflessibile fornendo solo get e put e nessuno degli altri metodi divertenti che SortedMap può darti.

Btw, NavigableMap

In realtà, SortedMap non ti dà molto di più oltre Map . Ma c'è qualcos'altro ...

SortedMap è stato sostituito da NavigableMap da Java 1.6 (le due classi standard che implementano SortedMap implementano anche NavigableMap ). NavigableMap ha tutti i tipi di chiamate di metodo divertenti che sono spesso abbastanza utili.

    
risposta data 24.02.2015 - 02:53
fonte
-1

Mentre è vero che nella programmazione è sempre una buona idea

"use the most general interface possible"

è ancora più vero che

"everything should be as simple as possible --but not simpler".

Quindi, se il tuo codice ha solo bisogno di lavorare con un Map , allora al tuo codice dovrebbe essere dato un Map e niente di più specifico di quello. In questo modo, il tuo codice funzionerà quando gli verrà passato un Map o un SortedMap , e il codice che usa il tuo codice sarà in grado di passarlo come meglio si adatta alle sue esigenze.

Tuttavia , se il tuo codice ha bisogno di lavorare con SortedMap , non puoi in qualche modo aggirarlo e continuare a usare Map con la falsa finzione di mantenere le cose semplici; il tuo codice, ovviamente, dovrà ricevere un SortedMap . Questo succederà se il tuo codice deve utilizzare qualsiasi metodo specifico per SortedMap (non esiste in Map ) cioè comparator() , subMap() , headMap() , tailMap() , firstKey() , e lastKey() .

Quanto sopra è stato abbastanza autoesplicativo, quindi sospetto che il motivo per cui stai ponendo la domanda sia perché hai frainteso cosa sia SortedMap . Quindi, ecco alcune note sulla tua domanda:

They compile to the same bytecode [I think]

SortedMap è un'interfaccia senza alcun metodo default , non viene realmente compilato in bytecode. Il file .class di tale interfaccia non contiene nient'altro che dichiarazioni di funzioni. Ora, alcuni dei metodi dichiarati da SortedMap sono anche dichiarati da Map , e il motivo per cui queste dichiarazioni sono state duplicate in SortedMap era probabilmente per aggiungere nuova documentazione, ma molti metodi di SortedMap non esistono in Map .

(Lettura utile: Qual è la differenza tra dichiarazione e definizione in Java? )

No additional safety is provided since the compiler can't tell any of the differences between the two

Eh? Questo non ha alcun senso. Non sono sicuro di cosa stai pensando, ma qualunque cosa sia, probabilmente è sbagliato.

SortedMap does offer an extra non-compiler-checked post condition, namely that the iterator is sorted

SortedMap inizia con un commento del doc che è lungo circa 4 kilobyte, spiegando di cosa si tratta e in che modo si differenzia da Map . Non sono sicuro che sia una buona idea riassumere questo come "offre una condizione di post extra per il compilatore non compilato". Forse dovresti leggere la documentazione.

    
risposta data 24.02.2015 - 14:19
fonte

Leggi altre domande sui tag