2011-07-05 8 views
11

JavaのArrayListとScalaのListのパフォーマンスを比較するコードを書く必要があります。私はJavaコードでScala Listが動作するのに苦労しています。 Scala ListをJavaコード(.javaファイル内)で作成し、それに100個の乱数を追加する方法の実際の単純な「hello world」の例を投稿できますか?scala.collection.immutable.ListをJavaコードで使用する方法

PS:私はJavaをよく使いますが、Scalaを使ったことはありません。

+0

Java ArrayListコンパイルを使って、比較のために実行するScalaコードを書くことができると思います。後で両方ともJVMで実行されます。 JavaでScalaのリストをインポートできるかどうかは不明です。しかし、私はScala n00bです。おそらく間違っている。 – Nishant

+0

java.util.Listに相当するScalaは、collection.mutable.Bufferです。 – David

+1

どのようなテストですか?どのようなシナリオですか?どのアルゴリズム?スカラリストはデフォルトでは不変であり、関数型プログラミングパターンで使用されるはずです。それはJavaからそれらを使用する意味がありません。 Scala 'ArrayList'と非常によく似た' ArrayBuffer'を試すことができます。 – paradigmatic

答えて

13

それは周りに他の方法よりも、ScalaでJavaコレクションを使用する方が簡単ですが、あなたが求めているので:

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; 
    } 
} 

これはクラスパスにScalaの-library.jarでのjavacでコンパイル:

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

あなたはScalaのREPLから呼び出すことができます。

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

はスカラ座からJavaコレクションを使用するには、特別な何かをする必要はありません。

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

ありがとう、私はJavaに固執する必要があります。あなたがjavaのために投稿したコード、私はいくつかの質問があります。コードは少し奇妙に見えますが、特に "$コロン$コロン"はどこかで私が読むことができますか?質問2:「1」と「2」のリストですか?私はちょっと混乱しているのですが、あなたが空リストの意味を作成した後、正確に2行を説明してください。ありがとう – Shaunak

+0

$コロン$コロンはスカラの::クラスです。 $コロン$コロン$ .MODULE $は::コンパニオンオブジェクトです。 "one"行は、1 :: nilのために生成されたバイトコードのJavaへの変換です。これは::。apply(1、nil)と書くことができます。 Scalaコードのコンパイル方法を知りたければ、出力でjavapを実行してください。 –

+0

@スハナク。あなたが本当にあなたがそれらを使用したい場合は、スカラリストについての読書を少し時間を費やすべきです。ここではステップ9を参照してください:http://www.artima.com/scalazine/articles/steps.html – paradigmatic

0

私は最も簡単なルートは、Javaインターフェイスで始まり、scalaで実装することだと思います。たとえば、scala内のscalaリストの周りにjava.util.List-implementationを作成します。通常、このように:

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

スカラを使用することは私の選択肢ではありません。私はjavaの他のライブラリも比較しているからです。特に家事の問題やJavaのようなものが強制されているためです。 – Shaunak

12

何恐ろしい比較を!私はあなたが望むものを達成する方法を説明するために他の人にそれを残しておきますが、ここではこれも試したことがない理由いくつかの理由です:

  1. ScalaのListは、永続的な、不変コレクションですが、ArrayListは可変コレクションです;
    1. つまり、コンテンツが保存される必要がある場合は、Listでそのようなことは必要ありませんが、ArrayListをコピーする必要があります。
    2. また、ArrayListのサポート操作は、Listでは実行できません。
  2. は、一定時間の前に、ArrayListが償却された一定時間の追加を持っています。両方とも、他の操作に線形時間があります。
  3. ArrayListには一定時間のインデックス付きアクセスがあり、Listには線形時間インデックスアクセスがありますが、これは意図した使用モードではありません。
  4. Listは、クロージャを使用foreachmapfilterとして、ArrayListは、外部イテレータまたはインデックスを介してトラバースされる、自己トラバース方法によって使用されるべきです。

したがって、基本的には、どちらも効率的な操作で吸い取り、あるアルゴリズムで使用されるアルゴリズムは、他のアルゴリズムと一緒に使用しないでください。それは不変です - あなたはScalaのListに要素を追加しないScalaのリストを作成し、それに

を言う100個の 乱数を追加

:あなたが提案する非常にベンチマークを考えてみましょう。既存のListと新しい要素に基づいて、新しいListを作成します。結局、あなたは100種類のリスト(サイズ1〜100)を持っています。これらのリストはすべて変更せずに使用できます。一方、ArrayListに100個の要素を追加すると、ArrayListのサイズは100になります。したがって、時間差が何であれ、それぞれの操作は異なるものでした。

編集

私はここの要素を付加するList自体にメソッドを使用していますnatenのコード、わずかに異なるバージョンの掲載、代わりに工場を呼んでいます。

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; 
    } 
} 

そして、彼にあなたの質問への答えに、$colon$colon要素を付加するために使用される方法であることという、ScalaはJVM方法::を表している方法です。また、このメソッドは、操作の性質を反映して、左ではなく右にバインドします。その理由は、nil::1の代わりに1::nilというコメントが使用されている理由です。

シングルトンであるため、空のリストNil$.MODULE$が新たに作成される代わりに参照されます。空のリストを作成する方法はありません。

20

java内からscala.collection.JavaConversionsを使用します。

そのコンストラクタでScalaのリストを必要とネストされたScalaのケースクラスを作成する例:

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; 
} 
を次のようにあなたが(x)は.toList()asScalaBufferを使用することができますJavaから

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

+0

この回答は、2年後に投稿された可能性がありますので、ここに投稿された他のものよりもかなり良いようです。なぜそれがもっと注目されていないのか分かりません。素晴らしい答えをありがとう! – Maciek

+0

私もこの回答を推進しています! – Mahdi

関連する問題