Scala List, распараллеливаемый и вызывающий из Java
У меня есть scala.collection.immutable.List[WeatherData]
В Scala я могу превратить его в параллельную коллекцию и вызвать метод Reduce:
val sum = myList.par.reduce(_+_)
Я хочу сделать то же самое в Java, но не могу. Прежде всего, Eclipse сообщает мне, что сигнатура #par() возвращает ParSeq[WeatherData], но если я попрошу Eclipse назначить результат локальной переменной, он даст мне scala.collection.parallel.ParIterable<WeatherData>
,
В любом случае, ни один из этих интерфейсов не имеет таких методов, как #reduce(...)
так что они не помогают.
Что мне нужно сделать, чтобы я мог позвонить #reduce(...)
с Java?
Ура, Джон
PS использую Scala 2.10 M5
1 ответ
Я написал несколько Scala:
val data = List(1,2,3)
val par = data.par
val result = par.reduce(_+_)
println(result)
Используя Java Decompiler, это, очевидно, так:
List localList = List..MODULE$.apply(Predef..MODULE$.wrapIntArray(new int[] { 1, 2, 3 }));
ParSeq localParSeq = (ParSeq)localList.par();
Немного поправив, я попробовал эту Java:
List localList = List$.MODULE$.apply(Predef$.MODULE$.wrapRefArray(new Integer[] { 1, 2, 3 }));
ParSeq localParSeq = (ParSeq)localList.par();
И, как писал Луиджи, это приводит к странному NoSuchMethodException
,
Я перешел на следующий уровень и использовал javap -verbose
, который дал это:
29: invokeinterface #40, 1; //InterfaceMethod scala/collection/Parallelizable.par:()Lscala/collection/Parallel;
Это заставило меня задуматься, что произойдет, если я брошу Parallelizable
перед звонком par
в Java:
List localList = List$.MODULE$.apply(Predef$.MODULE$.wrapRefArray(new Integer[] { 1, 2, 3 }));
Parallelizable p = (Parallelizable)localList;
Parallel p2 = p.par();
Integer result = (Integer) ((ParSeq)p2).reduce(adder);
System.out.println(result);
Это печатает 6
, какой правильный:-)
Но я должен признать, я понятия не имею, почему я должен бросить. Это заставило меня понять, что мне еще многое предстоит узнать о Java и Scala.
Кто-нибудь знает, почему актерский состав имеет значение?