2

これは正常にコンパイルされますが、実行時に次のように爆発します。

スレッド"main"の例外java.lang.NoSuchMethodError:scala.collection.immutable.List.filter(Lscala / Function1;)Lscala / collection / immutable / List

import scala.Function1;
import scala.collection.immutable.List;
import scala.collection.immutable.Nil$;
import scala.runtime.AbstractFunction1;

public class FunProc {
    List nil = Nil$.MODULE$;                      // the empty list
    List<Integer> list1 = nil.$colon$colon(1);    // append 1 to the empty list
    List<Integer> list2 = list1.$colon$colon(2);  // append 2 to List(1)
    List<Integer> list3 = list2.$colon$colon(3).$colon$colon(14).$colon$colon(8); // List(8, 14, 3, 2, 1)

    Function1<Integer, Object> filterFn = new AbstractFunction1<Integer, Object>() {
        public Boolean apply(Integer value) { return value<10; }
    };

    List<Integer> list4 = list3.filter(filterFn); // List(8, 3, 2, 1)

    public void doIt() {
        System.out.println("Filtered List is " + list4);
    }
}

編集

idonnieの答えを試した後、私はこれを思いついた:

List<Integer> list4 = list3.toTraversable().filter(filterFn).toList();

これは、キャストの代わりに変換が使用されることを除いて、基本的にidonnieの回答と同じです。次のコンパイルが正常に行われることを考えると、toTraversable()が必要な理由を知りたいと思います。

List<Integer> list4 = list3.filter(filterFn);
4

4 に答える 4

5

私のため、

$ 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

idonnieのTraversableは大丈夫です。

FWIW、scaladocは、IDEを嫌う私たちのために、「定義クラス」を示しています。

これは、一貫性のないJavaジェネリック署名の症状である可能性があり、議論分析は途方もないものです。

しかしscalac -Ycheck:jvm TraversableLike.scala、フィルターについては文句を言いません。(そのMLスレッドに関する私のコメントは、「コンパイラーは警告を発した後、addGenericSignatureから脱却する」でした。私の修正は、相互運用をサポートするためにScalaにキャストを追加することでした。)

于 2012-12-13T01:47:22.100 に答える
2

を通じてjavap、最終的にscala.collection.TraversableLikeでフィルターメソッドを見つけました

編集

コンパイルして実行します:

    List<Integer> list4 = (List<Integer>)
(((scala.collection.TraversableLike) list3).filter(filterFn));
于 2012-12-13T00:31:04.577 に答える
2

FunctionNとそのサブクラスを使用して、JavaのScalaリストAbstractFunctionNなどの操作を実行できます。filter()Scalaリストを作成してフィルタリングする方法は次のとおりです。

// List(8, 3, 2, 1)
List<Integer> list4a = list3.toTraversable().filter(filterFn).toList(); 

この手法は、インスタンスを返すリストでTraversableLike呼び出すために、トレイトによって提供されるメソッドへのアクセスを取得します。次に呼び出すことができ、別のインスタンスを返します。が呼び出され、インスタンスをに変換し直します。toTraversable()Traversable<Integer>filter()Traversable<Integer>TraversabletoList()Traversable<Integer>List<Integer>

som-snyttが参照するScalaコンパイラのバグが次の方法でどのように軽減されるのかわかりません。

// this produces the same result: List(8, 3, 2, 1)
List<Integer> list4b = 
    (List<Integer>) ((scala.collection.TraversableLike) list3).filter(filterFn));

filterFn()Function1サブクラスのインスタンスですAbstractFunction1。このインスタンスは、Javaに対してとして定義されています。Function1<Integer, Object>これは、を受け入れてIntegerを返すことを意味しますObject。Scalaで記述されているように、apply()メソッド定義は実際にはを返しますがscala.Boolean、Javaはnot know aboutscala.Boolean . Instead, we defineapply()to return ajava.lang.Booleanを実行し、戻り値のtypeパラメーターはとして宣言されjava.Objectます。これがより適切に機能する方法を理解したいと思います。

于 2012-12-13T22:01:43.617 に答える
1

これはすべて私には疑わしいように聞こえます。

まず、特性の使用はそれとは何の関係もないはずだと述べさせてください。トレイトを使用する場合、Scalaはそれらのトレイトを実装する静的メソッドへのフォワーダーを作成するため、トレイトまたはクラスによって定義されたメソッドを呼び出しても、まったく違いはありません。

filter第二に、私は次のように与えられたの定義に問題は見られませんjavap

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

したがって、メソッドはそこにあり、型シグネチャは正しいようです。私はこの問題をscalaメーリングリストに持っていきますが、これについてはすでにいくつかの問題が開いていることは間違いありません。

于 2012-12-18T11:45:30.727 に答える