Sha*_*nak 14 java performance scala list
我需要编写一个代码来比较Java ArrayList与Scala的性能List.我很难让Scala List在我的Java代码中工作.有人可以发布一个真正简单的"hello world"示例,说明如何List在java代码中创建Scala (在.java文件中)并添加100个随机数吗?
PS:我非常擅长Java,但从未使用过Scala.
sim*_*905 22
从java内部使用scala.collection.JavaConversions.
例如,要创建一个嵌套的scala案例类,在其构造函数中需要一个scala List:
case class CardDrawn(player: Long, card: Int)
case class CardSet(cards: List[CardDrawn])
Run Code Online (Sandbox Code Playgroud)
从Java可以使用asScalaBuffer(x).toList(),如下所示:
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;
}
Run Code Online (Sandbox Code Playgroud)
Nat*_*rom 15
在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;
}
}
Run Code Online (Sandbox Code Playgroud)
这在类路径中使用scala-library.jar编译javac:
javac -classpath /opt/local/share/scala-2.9/lib/scala-library.jar foo.java
Run Code Online (Sandbox Code Playgroud)
您可以从Scala REPL调用:
scala> (new foo).test
List(1)
List(2, 1)
res0: List[Any] = List(2, 1)
Run Code Online (Sandbox Code Playgroud)
要使用Scala中的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]
Run Code Online (Sandbox Code Playgroud)
Dan*_*ral 14
多么可怕的比较!我会把它留给其他人解释如何完成你想要的东西,但这里有几个原因甚至不应该尝试:
List是一个持久的,不可变的集合,ArrayList是一个可变的集合;
ArrayList必须在传递给可能改变它的方法之前复制,如果必须保留内容,而不需要这样做List;ArrayList支持行动不可能List;List有固定时间前置,ArrayList已摊销常数时间附加.两者都具有线性时间的其他操作.ArrayList具有恒定时间索引访问,List具有线性时间索引访问,这无论如何都不是预期的使用模式;List应该通过自遍遍方法使用,例如foreach,map和filter,使用闭包,ArrayList通过迭代器或索引从外部遍历.所以,基本上,每个人都会对另一个人的高效操作感到厌烦,并且一个人使用的算法不应该与另一个人一起使用.让我们考虑你提出的基准:
创建一个scala列表并添加100个随机数
您不向Scala添加元素List- 它是不可变的.您可以List基于现有List元素和新元素创建新元素.最后,您将拥有100个不同的列表(大小为1到100),所有这些列表都可以在不更改其他列表的情况下使用.同时,如果你向a添加100个元素ArrayList,你将拥有100个元素ArrayList.因此,无论时间差异如何,每个操作都会做出不同的操作.
编辑
我在这里发布了一个略有不同版本的naten代码,它使用一种方法List来预先添加一个元素,而不是调用工厂.
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;
}
}
Run Code Online (Sandbox Code Playgroud)
并且,在回答您的问题时,$colon$colonScala是如何表示::JVM中的方法,即用于预先添加元素的方法.此外,该方法绑定到右侧而不是左侧,反映了操作的性质,这就是注释的原因1::nil而不是nil::1.
Nil$.MODULE$引用空列表,而不是重新创建,因为它是单例 - 没有办法创建空列表.