如何在 Java 代码中使用 scala.collection.immutable.List
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6578615/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to use scala.collection.immutable.List in a Java code
提问by Shaunak
I need to write a code that compares performance of Java's ArrayListwith Scala's List. I am having a hard time getting the Scala Listworking in my Java code. Can some one post a real simple "hello world" example of how to create a Scala Listin java code (in a .javafile) and add say 100 random numbers to it?
我需要编写一个代码来比较 JavaArrayList和 Scala 的性能List。我很难让 ScalaList在我的 Java 代码中工作。有人可以发布一个真正简单的“hello world”示例,说明如何List在 Java 代码(在.java文件中)创建 Scala并向其中添加 100 个随机数?
PS: I am quite good at Java but have never used Scala.
PS:我非常擅长Java,但从未使用过Scala。
采纳答案by Nate Nystrom
It's easier to use Java collections in Scala than the other way around, but since you asked:
在 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;
}
}
This compiles with javac with scala-library.jar in the classpath:
这与 javac 与类路径中的 scala-library.jar 一起编译:
javac -classpath /opt/local/share/scala-2.9/lib/scala-library.jar foo.java
You can invoke from the Scala REPL:
您可以从 Scala REPL 调用:
scala> (new foo).test
List(1)
List(2, 1)
res0: List[Any] = List(2, 1)
To use a Java collection from Scala, you don't have to do anything special:
要使用 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]
回答by simbo1905
Use scala.collection.JavaConversions from inside of java.
从 java 内部使用 scala.collection.JavaConversions。
For example to create a nested scala case class that requires a scala List in its constructor:
例如,创建一个嵌套的 scala case 类,在其构造函数中需要一个 scala 列表:
case class CardDrawn(player: Long, card: Int)
case class CardSet(cards: List[CardDrawn])
From Java you can use asScalaBuffer(x).toList() as follows:
在 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;
}
回答by Daniel C. Sobral
What an horrible comparison! I'll leave it to others to explain how to accomplish what you want, but here's a few reasons why this shouldn't even be tried:
多么可怕的对比!我会把它留给其他人来解释如何完成你想要的,但这里有一些为什么不应该尝试的原因:
- Scala's
Listis a persistent, immutable collection,ArrayListis a mutable collection;- That means
ArrayListmust be copied before passed to methods that may change it, if the content must be preserved, while no such thing is necessary withList; - It also mean that
ArrayListsupport operations not possible inList;
- That means
Listhas constant-time prepend,ArrayListhas amortized constant-time append. Both have linear time the other operation.ArrayListhas constant-time indexed access,Listhas linear time indexed access, which is not the intended mode of use anyway;Listshould be used through self-traversing methods, such asforeach,mapandfilter, which use closures,ArrayListis externally traversed through an iterator or index.
- Scala的
List是一个持久的、不可变的集合,ArrayList是一个可变的集合;- 这意味着
ArrayList必须在传递给可能改变它的方法之前复制它,如果必须保留内容,而没有这样的事情List; - 这也意味着
ArrayList支持操作在List;
- 这意味着
List具有固定时间前置,ArrayList已摊销固定时间附加。两者都具有其他操作的线性时间。ArrayList具有恒定时间索引访问,List具有线性时间索引访问,无论如何这不是预期的使用模式;List应该通过自我遍历的方法,如可以使用foreach,map并且filter,其中使用封闭件,ArrayList通过一个迭代或索引外部穿过。
So, basically, each suck at the other's efficient operations, and the very algorithms used with one shouldn't be used with the other. Let's consider the very benchmark you propose:
所以,基本上,每个人都讨厌另一个人的高效操作,并且不应该与另一个一起使用与一个一起使用的算法。让我们考虑一下您提出的基准:
create a scala List and add say 100 random numbers to it
创建一个 Scala 列表并向其中添加 100 个随机数
You don't add elements to a Scala List-- it is immutable. You create a new Listbased on an existing Listand a new element. In the end, you'll have 100 different lists (of sizes 1 to 100), all of which can be used without changing the other. Meanwhile, if you add 100 elements to an ArrayList, you'll have one ArrayListof size 100. So, whatever the time difference is, each operation did something different.
您不会向 Scala 添加元素List——它是不可变的。您List根据现有List元素和新元素创建新元素。最后,您将拥有 100 个不同的列表(大小为 1 到 100),所有这些列表都可以在不更改另一个的情况下使用。同时,如果将 100 个元素添加到ArrayList,您将拥有一个ArrayList大小为 100 的元素。因此,无论时间差是多少,每个操作都会执行不同的操作。
Edit
编辑
I'm posting here a slightly different version of naten's code, which uses a method on Listitself to prepend an element, instead of calling a factory.
我在这里发布了 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;
}
}
And, in answer to your question to him, $colon$colonis how Scala represents the method ::in the JVM, that being the method used to prepend elements. Also, that method binds to the right instead of the left, reflecting the nature of the operation, which is why the comment is 1::nilinstead of nil::1.
并且,在回答您向他提出的问题时,$colon$colonScala 如何表示::JVM 中的方法,即用于添加元素的方法。此外,该方法绑定到右侧而不是左侧,反映了操作的性质,这就是为什么注释1::nil不是nil::1。
The empty list, Nil$.MODULE$, is referenced instead of created anew because it's a singleton -- there's no way to create an empty list.
空列表 ,Nil$.MODULE$被引用而不是重新创建,因为它是一个单例——无法创建空列表。
回答by thoredge
I think the easiest route would be to start with a java interface and implement that in scala. For example create a java.util.List-implementation around the scala list in scala. Typically like this:
我认为最简单的方法是从 java 接口开始并在 Scala 中实现它。例如,围绕 scala 中的 scala 列表创建一个 java.util.List 实现。通常是这样的:
class ScalaList[T](val ts: T*) extends java.util.List[T] {
// Add all the methods, but implement only the neccessary ones
// Add all ts
}

