L'unità sta testando il codice Java da ScalaTest e desidero popolare una java.util.HashMap all'interno della stessa istruzione dichiarata. È possibile farlo in Scala?Come popolare java.util.HashMap al volo dal codice Scala?
risposta
Ci sono un sacco di modi diversi per raggiungere questo obiettivo , solo alcuni dei quali sono apparsi nelle risposte fino ad ora.
Metodo Uno: Dal java.util.HashMap
ha il costruttore HashMap(Map<? extends K,? extends V> m)
, si potrebbe passare un Java Map valida. E si può fare questo banalmente con la Scala di utili JavaConversions
:
scala> import scala.collection.JavaConversions._
import scala.collection.JavaConversions._
scala> val myMap = Map(1->"Hi",2->"Bye")
myMap: scala.collection.immutable.Map[Int,java.lang.String] = Map((1,Hi), (2,Bye))
scala> val jmap = new java.util.HashMap[Int,String](myMap) // Need explicit types
jmap: java.util.HashMap[Int,String] = {1=Hi, 2=Bye}
Gli aspetti negativi qui sono che si deve avere già una mappa Scala (un po 'uno spreco se si sta solo andando a creare un Java uno, forse), e che devi specificare i tipi. Ma è compatto e indolore.
Metodo due: In alternativa, è possibile creare un nuovo blocco di codice come istruzione di dichiarazione, in modo che non hanno nemmeno bisogno di avere a disposizione JavaConversions
:
scala> val jmap2 = {
| val x = new java.util.HashMap[Int,String]
| for ((k,v) <- List(1->"Howdy",2->"partner")) x.put(k,v)
| x
| }
jmap2: java.util.HashMap[Int,String] = {1=Howdy, 2=partner}
Un po 'meno compatta, ma del tutto generale, e altrettanto efficiente (o inefficiente) come ci si preoccupa di farlo.
Metodo Tre: Inoltre, è possibile creare una sottoclasse anonima di HashMap fintanto che bene avere una sottoclasse (cioè .getClass
non tornerà java.util.HashMap
), e utilizzare l'inizializzatore per impostare i tuoi valori:
scala> val jmap3 = new java.util.HashMap[Int,String] {
| put(1,"Yo"); put(2,"bro")
| }
jmap3: java.util.HashMap[Int,String] = {1=Yo, 2=bro}
scala> jmap3.getClass.getName
res0: java.lang.String = $anon$1
scala> jmap3.getClass.getSuperclass.getName
res1: java.lang.String = java.util.HashMap
il rovescio della medaglia è, naturalmente, che si tratta di una sottoclasse di HashMap
piuttosto che HashMap
, ma è più compatta rispetto alla versione assegnazione-da-code-block dal momento che non c'è bisogno di assegnare la nuova mappa ad un val.
Metodo quattro: E infine, naturalmente, è possibile creare un metodo che fa quello che si vuole e chiamare invece:
scala> def newJHM[A,B](kv: Iterable[(A,B)]) = {
| val jhm = new java.util.HashMap[A,B]
| kv.foreach(i => jhm.put(i._1,i._2))
| jhm
| }
newJHM: [A,B](kv: Iterable[(A, B)])java.util.HashMap[A,B]
scala> val jmap4 = newJHM(Seq(1->"Bye",2->"Now")) // Type inference now works
jmap4: java.util.HashMap[Int,java.lang.String] = {1=Bye, 2=Now}
Questo è poco meno compatto rispetto agli altri e ottiene i tipi corretta senza che tu debba specificarli, quindi può essere una scelta interessante se la stai facendo più di una volta.
P.S. Solo per divertimento, ho mostrato una varietà di modi per ottenere alcune coppie chiave-valore nella mappa, ma non sono specifiche per un determinato metodo (eccetto per il numero 1 che richiede una mappa). Mescola e abbina secondo le tue preferenze.
Tutti i metodi e i costruttori di java.util.HashMap
sono a vostra disposizione, ovviamente, ma non forniscono un modo per inizializzare una mappa a meno che non ne abbia un altro per fornire i valori iniziali. Il più vicino probabilmente stai andando a ottenere è:
import java.util.HashMap
val jhm = new HashMap[String, Int]
«code to add key-value pairs to jhm»
Sulla risposta di Randall, è possibile utilizzare JavaConversions
per aiutare un po '.
import collection.JavaConversions.asMap
import java.util.HashMap
val jhm = new HashMap[Int,String](Map(1->"one", 2->"two"))
Si potrebbe fare la mappa come una classe anonima, e fare l'inizializzazione come parte dell'istanza inizializzazione dell'oggetto.
import java.util.HashMap
val jhm = new HashMap[String, Int](){
put(key1, value1)
put(key2, value2)
}
Questo in realtà funziona altrettanto bene in Java (tranne che per richiedere doppie parentesi graffe {{}}), ma è molto più idiomatica a Scala.
Non penso che ci sia qualcosa come l'inizializzazione statica di un oggetto. Suppongo che tu ti stia riferendo ad un inizializzatore di istanze, vero? –
corretto. Editing –
Tecnicamente, Scala non ha inizializzatori di istanza. Il codice che mostri sta eseguendo i metodi 'put' all'interno del * costruttore * per la classe interna anonima. –
Per rendere qualcosa riutilizzabile, sarebbe possibile creare un nuovo sottotipo "Mappa" solo per la sintassi di inizializzazione.
Potrebbe funzionare qualcosa come questo (sto ignorando i generici perché io non li uso regolarmente e avrei probabilmente ottenere qualcosa che non va):
HashMap hm=new HashMap(
new InitMap(
new String[]{"one", "two", "three"},
new int[] { 1 , 2 , 3 };
)
);
Non ci sarebbe più codice coinvolti nel InitMap classe ma sarebbe riutilizzabile e abbastanza diretto (mi piace molto la sintassi di inizializzazione degli array per questo genere di cose).
Pensandoci, la classe InitMap non sarebbe troppo difficile. Probabilmente vorresti capire quali metodi sono stati chiamati e implementarli. È probabile che chiamerebbe solo i metodi KeySet e EntrySet.
Naturalmente a questo ritmo si potrebbe semplice creare un metodo di supporto che ha preso i due array e ha restituito un HashMap o estendere HashMap e aggiungere un nuovo costruttore ...
- 1. Debug Python: modifica del codice al volo
- 2. Scarica il codice ed esegui al volo
- 3. Converti java.util.HashMap in scala.collection.immutable.Map in java
- 4. Scala permettendo chiamata al java.util.HashMap ottenere il metodo con il numero sbagliato di parametri
- 5. Converti EPS in PDF al volo con pdflatex al volo
- 6. PHPExcel scrivere al volo?
- 7. Come popolare 'selezionare' dal database in asp.net
- 8. Come istanziare e popolare un flusso Scala in Java?
- 9. aggiunta @ font-face al volo
- 10. Come creare oggetti al volo in python?
- 11. Come creare istanze al volo in CDI
- 12. creazione di metodi al volo
- 13. Come nominare le variabili al volo?
- 14. Creazione di sottodomini al volo
- 15. Modifica campi serializzatore al volo
- 16. Convalidare EmberJS TextField al volo?
- 17. Posso ottenere AST dal codice scala live?
- 18. Calcolo dei percentili al volo
- 19. Posso cambiare SparkContext.appName al volo?
- 20. Puoi cambiare templateUrl al volo?
- 21. Codice scala infinita scala
- 22. Come posso inviare SMS dal PC al cellulare in scala?
- 23. Popolare database Android dal file CSV?
- 24. Come generare un grande flusso di dati al volo
- 25. Angolare 2 - Aggiunta/rimozione componenti al volo
- 26. Caricamento plug-in Haskell al volo
- 27. git, lo schiacciamento si impegna al volo
- 28. Accesso al layout Qt creato nell'interfaccia utente dal codice?
- 29. Decrittografia audio/video al volo su MediaPlayer
- 30. Avvio del profiler Java HPROF al volo
Questa è un'ottima risposta. – eggonlegs