2011-07-05 14 views
11

Necesito escribir un código que compare el rendimiento de ArrayList de Java con el List de Scala. Estoy teniendo dificultades para obtener el Scala List trabajando en mi código Java. ¿Puede alguien publicar un ejemplo real de "Hola mundo" de cómo crear un Scala List en código java (en un archivo .java) y agregarle decir 100 números aleatorios a él?Cómo usar scala.collection.immutable.List en un código Java

PD: Soy bastante bueno en Java pero nunca he usado Scala.

+0

Supongo que puede escribir un código Scala que use Java ArrayList compilar y ejecutar para comparar ... después de todo, ambos se ejecutarán en JVM. No estoy seguro de si es posible importar la lista de Scala en Java. Pero soy un Scala n00b. Posiblemente mal. – Nishant

+0

El equivalente de Scala de java.util.List es collection.mutable.Buffer. – David

+1

¿Qué tipo de pruebas? ¿Qué escenarios? ¿Qué algoritmos? Las listas de Scala son inmutables por defecto y se supone que deben usarse con patrones de programación funcional. No tiene sentido usarlos de Java. Puedes probar 'ArrayBuffer' que es muy similar a Scala' ArrayList'. – paradigmatic

Respuesta

13

Es más fácil de usar colecciones de Java en Scala que la otra manera alrededor, pero ya que preguntas:

import scala.collection.immutable.*; 

public class foo { 
    public List test() { 
    List nil = Nil$.MODULE$; // the empty list 
    $colon$colon one = $colon$colon$.MODULE$.apply((Integer) 1, nil); // 1::nil 
    $colon$colon two = $colon$colon$.MODULE$.apply((Integer) 2, one); // 2::1::nil 
    System.out.println(one); 
    System.out.println(two); 
    return two; 
    } 
} 

Esto compila con javac con scala-library.jar en la ruta de clase :

javac -classpath /opt/local/share/scala-2.9/lib/scala-library.jar foo.java 

puede invocar desde la Scala REPL:

scala> (new foo).test 
List(1) 
List(2, 1) 
res0: List[Any] = List(2, 1) 

Para utilizar una colección de Java de Scala, usted no tiene que hacer nada especial:

scala> new java.util.ArrayList[Int] 
res1: java.util.ArrayList[Int] = [] 

scala> res1.add(1) 
res2: Boolean = true 

scala> res1 
res3: java.util.ArrayList[Int] = [1] 
+0

Gracias naten, tengo que quedarme con Java. el código que publicaste para Java, tengo algunas preguntas. El código parece un poco extraño, especialmente el "$ colon $ colon" ¿hay algún lugar donde pueda leer al respecto? Pregunta 2: ¿son listas 'una' y 'dos'? Estoy un poco confundido, ¿pueden explicar qué significan exactamente las dos líneas después de crear una lista vacía?gracias – Shaunak

+0

$ colon $ colon es la clase :: en Scala. $ colon $ colon $ .MODULE $ es el objeto :: compañero. La línea "uno" es solo una traducción a Java del bytecode generado para 1 :: nil, que podría escribirse ::. Apply (1, nil). Si desea saber cómo se compila el código de Scala, ejecute javap en la salida. –

+0

@Shaunak. Realmente debería pasar algún tiempo leyendo sobre las listas de scala si desea usarlas. Vea el paso 9 aquí: http://www.artima.com/scalazine/articles/steps.html – paradigmatic

0

Creo que la ruta más fácil sería comenzar con una interfaz java e implementarla en scala. Por ejemplo, cree una implementación java.util.List alrededor de la lista scala en scala. Normalmente desea:

class ScalaList[T](val ts: T*) extends java.util.List[T] { 

    // Add all the methods, but implement only the neccessary ones 
    // Add all ts 

} 
+0

usando scala no es una opción para mí. porque estoy comparando algunas otras bibliotecas en Java también. y especialmente porque se aplica el tipo de problema de trabajo a domicilio y java. – Shaunak

12

Lo que una comparación horrible! Lo dejo a los demás para explicar cómo llevar a cabo lo que quiere, pero aquí hay un par de razones por las cuales esto no debería ni siquiera ser juzgado:

  1. de List Scala es una colección permanente, inmutable, ArrayList es una colección mutable ;
    1. Eso significa ArrayList deben copiarse antes de pasados ​​a los métodos que pueden cambiar, si el contenido debe ser preservada, mientras que tal cosa no es necesaria con List;
    2. También significa que ArrayList operaciones de soporte no son posibles en List;
  2. List tiene pre-tiempo constante, ArrayList ha amortizado el tiempo constante anexar. Ambos tienen tiempo lineal en la otra operación.
  3. ArrayList tiene acceso indexado en tiempo constante, List tiene acceso indexado en tiempo lineal, que no es el modo de uso previsto de todos modos;
  4. List debe usarse a través de métodos de auto-de desplazamiento, tal como foreach, map y filter, que utilizan cierres, ArrayList está atravesado externamente a través de un iterador o índice.

Por lo tanto, básicamente, cada una de las operaciones eficaces de la otra, y los mismos algoritmos utilizados con uno no se deben utilizar con el otro.Vamos a considerar el punto de referencia que se propone:

crear una lista Scala y añadir decir 100 números aleatorios para que

No añadir elementos a un List Scala - es inmutable. Crea un nuevo List basado en un List existente y un nuevo elemento. Al final, tendrá 100 listas diferentes (de tamaños 1 a 100), todas las cuales se pueden usar sin cambiar la otra. Mientras tanto, si agrega 100 elementos a un ArrayList, tendrá un ArrayList de tamaño 100. Por lo tanto, cualquiera que sea la diferencia horaria, cada operación hizo algo diferente.

Editar

les dejo aquí una versión ligeramente diferente del código de naten, que utiliza un método en sí List a anteponer un elemento, en lugar de llamar a una fábrica.

import scala.collection.immutable.*; 

public class Foo { 
    public List test() { 
    List nil = Nil$.MODULE$; // the empty list 
    List one = nil.$colon$colon((Integer) 1); // 1::nil 
    List two = one.$colon$colon((Integer) 2); // 2::1::nil 
    System.out.println(one); 
    System.out.println(two); 
    return two; 
    } 
} 

Y, en respuesta a su pregunta a él, es como $colon$colon Scala representa el método :: en la JVM, que siendo el método utilizado para anteponer elementos. Además, ese método se une a la derecha en lugar de a la izquierda, lo que refleja la naturaleza de la operación, por lo que el comentario es 1::nil en lugar de nil::1.

Se hace referencia a la lista vacía, Nil$.MODULE$, en lugar de crearla de nuevo porque es un singleton; no hay forma de crear una lista vacía.

20

Usa scala.collection.JavaConversions desde dentro de java.

Por ejemplo, para crear una clase anidada caso Scala que requiere una Lista Scala de su constructor:

case class CardDrawn(player: Long, card: Int) 
case class CardSet(cards: List[CardDrawn]) 

De Java puede utilizar asScalaBuffer (x) .toList() de la siguiente manera:

import scala.collection.JavaConversions; 
import java.util.ArrayList; 
import java.util.List; 

public CardSet buildCardSet(Set<Widget> widgets) { 

    List<CardDrawn> cardObjects = new ArrayList<>(); 

    for(Widget t : widgets) { 
    CardDrawn cd = new CardDrawn(t.player, t.card); 
    cardObjects.add(cd); 
    } 

    CardSet cs = new CardSet(JavaConversions.asScalaBuffer(cardObjects).toList()); 
    return cs; 
} 
+0

Esta respuesta parece bastante mejor que las otras publicadas aquí, tal vez porque se publicó 2 años después. No estoy seguro de por qué no recibe más atención. ¡Gracias por la gran respuesta! – Maciek

+0

¡Promuevo esta respuesta también! – Mahdi