【问题标题】:How to use array of scala.collection.immutable.List in java code如何在java代码中使用scala.collection.immutable.List数组
【发布时间】:2020-04-12 10:25:35
【问题描述】:

我是 scala 新手,我需要编写一个 java 代码,将 scala.collection.immutable.List 数组传递给 scala 函数。更具体地说,我在我的 java 代码中使用了一个 scala 函数,它需要 scala.collection.immutable.List<Tuple2<Object, Object>>[] 作为参数。对象必须是<Integer, Double>。在java中这很简单:

    java.util.List<Tuple2<Integer, Double>>[] javaList = new ArrayList[335];
            for (int i = 0; i < 335; i++) { 
                javaList[i] = new ArrayList<Tuple2<Integer, Double>>(); 
            } 
              for(int i=0; i<100;i++)
             {
                 for(int j=0; j<50;j++)
               {
                   javaList[i].add(new Tuple2<Integer, Double>(j, value(j)));
                }
             }

我需要或将其从 java 转换为 scala 或创建 scala.collection.immutable.List&lt;Tuple2&lt;Object, Object&gt;&gt;[] 并直接在我的 java 代码中使用它,但我很难找到它。我在一个 maven 项目中使用 Java 8、scala 2.12.2。

【问题讨论】:

  • ListsArray 是一种奇怪的数据结构。无论如何,Scala 标准库提供了转换 b>Java 集合** 到 Scala 集合中,反之亦然。我会在 Scala 中编写一个接收 Java 输入的函数,将其转换为 Scala 输入,然后调用 scala 函数。
  • 如果@varargs def f(vs: List[Int]*),列表数组就不那么奇怪了。
  • 我的问题是我无法更改函数中的 scala 参数:scala.collection.immutable.List>[] 所以我需要找到一种方法java编码这个结构。
  • @vicangel 最简单的方法是添加一个新的 Scala 函数,该函数接收一个易于从 Java 创建的数据结构并进行转换。

标签: java list scala


【解决方案1】:

我不知道我刚刚犯下的憎恶顺序是什么,但是:

class Target {
  @annotation.varargs
  def f(lists: List[(Int, Double)]*): Int = lists.map(_.map(_._1).sum).sum
}

然后

$ javap Target
Compiled from "scalafunc.scala"
public class Target {
  public int f(scala.collection.immutable.List<scala.Tuple2<java.lang.Object, java.lang.Object>>...);
  public int f(scala.collection.immutable.Seq<scala.collection.immutable.List<scala.Tuple2<java.lang.Object, java.lang.Object>>>);
  public static final int $anonfun$f$2(scala.Tuple2);
  public static final int $anonfun$f$1(scala.collection.immutable.List);
  public Target();
  public static final java.lang.Object $anonfun$f$1$adapted(scala.collection.immutable.List);
  public static final java.lang.Object $anonfun$f$2$adapted(scala.Tuple2);
}

并与 Scala 2.13 互操作:

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import scala.Tuple2;
import static scala.jdk.javaapi.CollectionConverters.asScala;

public class j {
  public static void main(String... args) {
    // populate an array list of lists
    var javaList = new ArrayList<ArrayList<Tuple2<Integer, Double>>>();
    for (int i = 0; i < 335; i++) {
      javaList.add(new ArrayList<Tuple2<Integer, Double>>());
    }
    for(int i=0; i<100;i++) {
      for(int j=0; j<50;j++) {
        javaList.get(i).add(new Tuple2<Integer, Double>(j, Double.valueOf(j)));
      }
    }
    // convert the elements to scala lists; the result happens to be an arraylist
    var arg = (ArrayList<scala.collection.immutable.List<Tuple2<Integer, Double>>>) javaList.stream().map(vs -> asScala(vs).toList()).collect(Collectors.toList());
    // we need an array of scala lists
    @SuppressWarnings("unchecked")
    var template = (scala.collection.immutable.List<Tuple2<Object, Object>>[]) Array.newInstance(scala.collection.immutable.List.class, arg.size());
    // extract the target array
    var fargs = arg.toArray(template);
    Target t = new Target();
    // call the varargs f
    var res = t.f(fargs);
    System.out.println(res);
  }
}

我可以

$ scalac scalafunc.scala 
$ javac -Xlint -cp .:/home/me/scala-2.13.1/lib/scala-library.jar j.java && java -cp .:/home/me/scala-2.13.1/lib/scala-library.jar j
122500

我没有验证这个结果;我并不完全有信心,因为它是用 Java 编译的。

【讨论】:

  • 我猜如果你从一个数组开始,你使用Arrays.asList(start).stream
猜你喜欢
  • 2011-09-28
  • 1970-01-01
  • 1970-01-01
  • 2013-08-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-12
  • 1970-01-01
相关资源
最近更新 更多