Come inizializzare una mappa Scala con più di 4 elementi iniziali in Java?

3

Per 4 o meno elementi, qualcosa di simile funziona (o almeno compila):

import scala.collection.immutable.Map;

Map<String,String> HAI_MAP = new Map4<>("Hello", "World",
                                        "Happy", "Birthday",
                                        "Merry", "XMas",
                                        "Bye", "For Now");

Per un quinto elemento I potrebbe fare questo:

Map<String,String> b = HAI_MAP.$plus(new Tuple2<>("Later", "Aligator"));

Ma voglio sapere come inizializzare una mappa immutabile con 5 o più elementi e sto agitando in Tipo-inferno.

Soluzione parziale

Ho pensato di capirlo rapidamente compilando ciò che volevo in Scala, quindi decompilando i file di classe risultanti. Ecco la scala:

object JavaMapTest {
  def main(args: Array[String]) = {
    val HAI_MAP = Map(("Hello", "World"),
                      ("Happy", "Birthday"),
                      ("Merry", "XMas"),
                      ("Bye", "For Now"),
                      ("Later", "Aligator"))
    println("My map is: " + HAI_MAP)
  }
}

Ma il decompilatore mi ha dato qualcosa che ha due periodi consecutivi e quindi non verrà compilato (non lo faccio pensa che questo sia valido Java):

scala.collection.immutable.Map HAI_MAP =
        (scala.collection.immutable.Map) 
        scala.Predef..MODULE$.Map().apply(scala.Predef..MODULE$.wrapRefArray(
                scala.Predef.wrapRefArray(
                        (Object[])new Tuple2[] {
                                new Tuple2("Hello", "World"),
                                new Tuple2("Happy", "Birthday"),
                                new Tuple2("Merry", "XMas"),
                                new Tuple2("Bye", "For Now"),
                                new Tuple2("Later", "Aligator") }));

Sono davvero sconcertato dai due periodi in questo:

scala.Predef..MODULE$

Ho chiesto informazioni su #java su Freenode e hanno detto che .. sembrava un bug del decompilatore. Non sembra voler compilare, quindi penso che probabilmente abbiano ragione. Ci sto provando quando cerco di esplorare le interfacce in IntelliJ e sono generalmente perduto.

In base alla mia sperimentazione, è valida quanto segue:

Tuple2[] x = new Tuple2[] { new Tuple2<String,String>("Hello", "World"),
                            new Tuple2<String,String>("Happy", "Birthday"),
                            new Tuple2<String,String>("Merry", "XMas"),
                            new Tuple2<String,String>("Bye", "For Now"),
                            new Tuple2<String,String>("Later", "Aligator") };

scala.collection.mutable.WrappedArray<Tuple2> y = scala.Predef.wrapRefArray(x);

Esiste anche un metodo WrappedArray.toMap() , ma i tipi di firma sono complicati e sto anche correndo nel problema del doppio periodo quando provo a ricercare le interfacce da Java.

    
posta GlenPeterson 29.06.2013 - 02:24
fonte

2 risposte

4

Il decompilatore ha probabilmente dei problemi nel decompilare correttamente i nomi delle classi che contengono un simbolo $ . Il simbolo che stai cercando è denominato Predef$ :

import scala.Predef;
import scala.Predef$;
import scala.Tuple2;
import scala.collection.immutable.Map;
import scala.collection.mutable.WrappedArray;

public class T {
  @SuppressWarnings({ "rawtypes", "unchecked" })
  public static void main(final String... args) {
    final Tuple2[] ts = { new Tuple2("a", "b") };
    final WrappedArray wa = Predef.wrapRefArray(ts);
    final Map<String, String> map = Predef$.MODULE$.Map().apply(wa);
    System.out.println(map);
  }
}

Pertanto, sottolineo di non utilizzare un decompilatore ma la rappresentazione interna dell'AST in scalac:

$ scala -print -e 'Map(("a", "b"))'
...
scala.this.Predef.Map().apply(
  scala.this.Predef.wrapRefArray(
    Array[Tuple2]{new Tuple2("a", "b")}.$asInstanceOf[Array[Object]]()));
...

Se sei interessato a maggiori informazioni su come lavorare con l'output di scalac, dai un'occhiata a questa domanda e le sue risposte.

    
risposta data 29.06.2013 - 11:27
fonte
1

Che ne dici di questo?

java.util.Map<String, String> javaMap = new java.util.HashMap<String, String>();
javaMap.put("Hello", "World");
javaMap.put("Happy", "Birthday");
javaMap.put("Merry", "XMas");
javaMap.put("Bye", "For Now");
javaMap.put("Later", "Aligator");

scala.collection.Map<String, String> scalaMap = scala.collection.JavaConversions$.MODULE$.asMap(javaMap);
System.out.println(scalaMap);
    
risposta data 29.06.2013 - 11:30
fonte

Leggi altre domande sui tag