从Java中筛选Scala列表
这可以很好地编译,但在运行时会出现以下情况: 线程“main”java.lang.NoSuchMethodError中出现异常:scala.collection.immutable.List.filter(Lscala/Function1;)Lscala/collection/immutable/List从Java中筛选Scala列表,scala,Scala,这可以很好地编译,但在运行时会出现以下情况: 线程“main”java.lang.NoSuchMethodError中出现异常:scala.collection.immutable.List.filter(Lscala/Function1;)Lscala/collection/immutable/List 导入scala.Function1; 导入scala.collection.immutable.List; 导入scala.collection.immutable.Nil$; 导入scala
导入scala.Function1;
导入scala.collection.immutable.List;
导入scala.collection.immutable.Nil$;
导入scala.runtime.AbstractFunction1;
公共类FunProc{
List nil=nil$.MODULE$;//空列表
List list1=nil.$colon$colon(1);//将1追加到空列表中
List list2=list1.$colon$colon(2);//将2追加到列表(1)
List list3=list2.$colon$colon(3)。$colon$colon(14)。$colon$colon(8);//List(8,14,3,2,1)
Function1 filterFn=新的AbstractFunction1(){
public Boolean apply(Integer value){return value通过javap
,最终在scala.collection.TraversableLike中找到了一个筛选方法
编辑
编译并运行:
List<Integer> list4 = (List<Integer>)
(((scala.collection.TraversableLike) list3).filter(filterFn));
List list4=(列表)
((scala.collection.TraversableLike)list3.filter(filterFn));
对我来说
$ javac -cp O\:/scala-2.10.0-RC2/lib/scala-library.jar jfilter/FunProc.java
jfilter\FunProc.java:19: error: incompatible types
List<Integer> list4 = list3.filter(filterFn); // List(1, 2, 3, 8)
^
required: List<Integer>
found: Traversable<Integer>
Note: jfilter\FunProc.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
1 error
$javac-cpo\:/scala-2.10.0-RC2/lib/scala-library.jar jfilter/FunProc.java
jfilter\FunProc.java:19:错误:类型不兼容
List list4=list3.filter(filterFn);//List(1,2,3,8)
^
必填项:列表
发现:可遍历
注意:jfilter\FunProc.java使用未经检查或不安全的操作。
注意:使用-Xlint重新编译:未选中以获取详细信息。
1错误
idonnie的可遍历性很好
FWIW,scaladoc为我们这些厌恶IDE的人显示了“定义类”
这可能是一种症状,包括和
但是scalac-Ycheck:jvm TraversableLike.scala
没有抱怨过滤器(我对该ML线程的评论是“编译器在发出警告后退出addGenericSignature”。我的修复方法是添加一个scala强制转换以支持互操作。)我们可以使用function n
及其abstractfunction n
子类对Java中的Scala列表执行filter()
等操作。下面是如何创建Scala列表并对其进行筛选
// List(8, 3, 2, 1)
List<Integer> list4a = list3.toTraversable().filter(filterFn).toList();
filterFn()
是Function1
子类AbstractFunction1
的一个实例。这个实例在Java中定义为Function1
,这意味着它接受一个整数
,并返回一个对象用Scala编写的方法定义实际上返回一个Scala.Boolean
,但是Java不知道Scala.Boolean。相反,我们定义了apply()返回一个
java.lang.Boolean,返回值的类型参数声明为java.Object
我想了解这是如何更正确地工作的。这一切听起来都很可疑
首先,让我声明trait的使用与此无关。当您使用trait时,Scala会创建到实现这些trait的静态方法的转发器,因此调用trait或类定义的方法应该不会有任何区别
其次,我认为javap
给出的filter
的定义没有问题:
public scala.collection.immutable.List<A> filter(scala.Function1<A, java.lang.Object>);
flags: ACC_PUBLIC
Code:
stack=2, locals=2, args_size=2
0: aload_0
1: aload_1
2: invokestatic #1103 // Method scala/collection/TraversableLike$class.filter:(Lscala/collection/TraversableLike;Lscala/Function1;)Ljava/lang/Object;
5: areturn
LineNumberTable:
line 76: 0
LocalVariableTable:
Start Length Slot Name Signature
0 6 0 this Lscala/collection/immutable/List;
0 6 1 p Lscala/Function1;
Signature: #1104 // (Lscala/Function1<TA;Ljava/lang/Object;>;)Lscala/collection/immutable/List<TA;>;
public scala.collection.immutable.List过滤器(scala.Function1);
旗帜:ACC_PUBLIC
代码:
堆栈=2,局部变量=2,参数大小=2
0:aload_0
1:aload_1
2:invokestatic#1103//方法scala/collection/TraversableLike$class.filter:(Lscala/collection/TraversableLike;Lscala/Function1;)Ljava/lang/Object;
5:轮到你了
LineNumberTable:
第76行:0
LocalVariableTable:
起始长度插槽名称签名
0 6 0此Lscala/集合/不可变/列表;
0 6 1 p Lscala/功能1;
签名:#1104/(Lscala/Function1;)Lscala/collection/immutable/List;
因此,方法就在那里,类型签名似乎是正确的。我会将此问题提交给scala邮件列表,尽管我愿意打赌这方面已经存在一些问题。:
是prepend,而不是appendI。我在调试器中查看了list3,它似乎已经正确构造。是的,这是可行的,但为什么呢?编译器发现filter(),否则它将无法编译。我不认为范围中的另一个筛选器()会导致任何歧义,那么为什么有必要将list3转换为TraversableLike?我可以理解转换为(List)的原因,因为Java只是看到一个对象从筛选器返回。也许有人能回答这个问题?AbstractTraversable
@idonnie链接到我回答中的一个常见嫌疑犯。@Mike Slinn,您的回答是“未接受”我的答案和StackOverflow对我收费-15???!你能不能不接受它,所以我不会担心我已经调查过,首先回答过-然后被收费-15?^)我接触了Scala语言,在那里,大部分Scala编译器的作者Paul Phillips说som snytt的答案是正确的。我承认som snytt的答案太难了读到这篇文章,我一开始并没有接受。这不是因为你的答案不正确,而是他的答案更正确。我感谢你抽出时间。我想知道你的答案为什么有效。我发布的问题说明了一个已知的编译器错误。你的答案并不是该错误的通用解决方案。非常感谢你的详细解释。Thanks,Daniel,会的!我同意这看起来很可疑。Paul Phillips说这是正确的答案,并且引用了。他比我更清楚!现在试着理解为什么这个答案是正确的…@MikeSlinn Paul只是说问题在于java泛型签名不一致。就我自己而言,我仍然看不出sig类型有什么问题2.9.2生成的特性,但它可能很棘手。
// List(8, 3, 2, 1)
List<Integer> list4a = list3.toTraversable().filter(filterFn).toList();
// this produces the same result: List(8, 3, 2, 1)
List<Integer> list4b =
(List<Integer>) ((scala.collection.TraversableLike) list3).filter(filterFn));
public scala.collection.immutable.List<A> filter(scala.Function1<A, java.lang.Object>);
flags: ACC_PUBLIC
Code:
stack=2, locals=2, args_size=2
0: aload_0
1: aload_1
2: invokestatic #1103 // Method scala/collection/TraversableLike$class.filter:(Lscala/collection/TraversableLike;Lscala/Function1;)Ljava/lang/Object;
5: areturn
LineNumberTable:
line 76: 0
LocalVariableTable:
Start Length Slot Name Signature
0 6 0 this Lscala/collection/immutable/List;
0 6 1 p Lscala/Function1;
Signature: #1104 // (Lscala/Function1<TA;Ljava/lang/Object;>;)Lscala/collection/immutable/List<TA;>;