2009-11-24 9 views
8

Questa è più una questione di stile e preferenza, ma qui va: quando dovrei usare scala.Array? Uso Elenco tutto il tempo e occasionalmente mi imbatto in Seq, Mappa e simili, ma non ho mai usato né visto Array in natura. È solo lì per la compatibilità con Java? Mi manca un caso d'uso comune?Quando dovrei usare Scala's Array invece di una delle altre raccolte?

+0

Devo fare di questo un wiki della comunità? – pr1001

+1

Io non la penso così. I pro e i contro dell'uso di Scala's Array sono abbastanza ben definiti e possono essere discussi obiettivamente. La domanda è valida, IMHO. –

risposta

12

Prima di tutto, facciamo un disclaimer qui. Array di Scala 2.7 prova ad essere un Java Array e una Collezione Scala allo stesso tempo. Succede per lo più, ma fallisce in entrambi i casi. Sfortunatamente, questi casi d'angolo possono accadere a brave persone con un codice normale, quindi Scala 2.8 si sta allontanando da quello.

Su Scala 2.8, c'è Array, che è Java Array. Ciò significa che è uno spazio di memoria contiguo, che memorizza i riferimenti o le primitive (e, quindi, può avere dimensioni di elementi differenti) e può essere acceduto in modo casuale piuttosto velocemente. Ha anche metodi schifosi, un'orribile implementazione toString e si comporta male quando si usano generici e primitivi allo stesso tempo (es .: def f[T](a: Array[T]) = ...; f(Array(1,2,3))).

E, quindi, c'è GenericArray, che è una Scala Collection supportata da un Array. Memorizza sempre le primitive in scatola, quindi non ha i problemi di prestazioni quando si mescolano primitive e generici, ma, d'altra parte, non ha i guadagni prestazionali di una matrice primitiva puramente primitiva (non generica).

Quindi, quando usare cosa? Un Array ha le seguenti caratteristiche:

  • O (1) lettura casuale e scrittura
  • O (n) di aggiunta/prepend/inserimento/cancellazione
  • mutevole

Se non lo fai Hai bisogno di generici, o i tuoi generici possono essere dichiarati come [T <: AnyRef], escludendo così le primitive, che sono AnyVal, e quelle caratteristiche sono ottimali per il tuo codice, quindi vai a prenderlo.

Se hai bisogno di generici, incluse le primitive, e quelle caratteristiche sono ottimali per il tuo codice, usa GenericArray su Scala 2.8. Inoltre, se desideri una raccolta vera e propria, con tutti i suoi metodi, potresti volerlo anche usare, invece di dipendere da conversioni implicite.

Se si desidera l'immutabilità o se è necessaria una buona prestazione per aggiungere, anteporre, inserire o eliminare, cercare un'altra raccolta.

+0

Grazie, Daniel, questa è un'ottima risposta. – pr1001

3

Una matrice è appropriata quando si dispone di un numero di elementi della stessa classe (o compatibile), e si conosce in anticipo il conteggio esatto di tali elementi o un limite superiore ragionevole e si è interessati al rapido casuale accesso e forse alterazione sul posto degli oggetti, ma dopo averlo configurato, non inserirai mai o rimuoverò mai elementi da qualche parte nella lista.

In altre parole, si tratta di una struttura di dati aggregata con meno campane e fischi dei tipi di raccolta, con un sovraccarico leggermente inferiore e prestazioni leggermente migliori a seconda di come viene utilizzata.

Un esempio molto ingegnoso: sei nel business della produzione di funzioni, e il test di qualità per queste funzioni consiste nel controllare le loro prestazioni o risultati per un set di 1000 valori di input fissi. Inoltre, decidi di non mantenere questi valori in un file, ma piuttosto li codifichi nel tuo programma. Un array sarebbe appropriato.

3

L'interfacciamento con le API Java è un caso. Inoltre, diversamente dagli array Java, gli array di livello sono invarianti e quindi non hanno alcun vantaggio sugli elenchi a causa di ciò.

Problemi correlati