Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何将Scala案例类和集合连接到Java_Java_Scala_Scala Java Interop - Fatal编程技术网

如何将Scala案例类和集合连接到Java

如何将Scala案例类和集合连接到Java,java,scala,scala-java-interop,Java,Scala,Scala Java Interop,我们在尝试使用Java中的Scala代码时遇到了问题。我们正在寻找一种方法来自动桥接各种Scala和java集合,而无需在java代码中显式转换。当只有很少的地方时,这样做是合理的,但是如果它分布广泛并且不断添加新的scala类,那么它就变得不切实际了 例如,在Scala代码中,我们有一些类似的类(其中很多): 当我们想用Java编写类似的代码时,它会变得非常麻烦,我们需要在所有地方添加许多辅助锅炉板: // JAVA // create a product HashMap<String,

我们在尝试使用Java中的Scala代码时遇到了问题。我们正在寻找一种方法来自动桥接各种Scala和java集合,而无需在java代码中显式转换。当只有很少的地方时,这样做是合理的,但是如果它分布广泛并且不断添加新的scala类,那么它就变得不切实际了

例如,在Scala代码中,我们有一些类似的类(其中很多):

当我们想用Java编写类似的代码时,它会变得非常麻烦,我们需要在所有地方添加许多辅助锅炉板:

// JAVA
// create a product
HashMap<String, String> attributes = new HashMap<String, String>();
attributes.put("my-attribute","my-value");

// create a scala collection
scala.collection.immutable.Map<String, String> scalaAttributes = Conversions.toScalaImmutableMap(attributes);

// create a product
Product p = Product("id","group",scalaAttributes)

// create a scala sequence of product
ArrayList<Product> dataFeedsProducts = new ArrayList<Product>();
        dataFeedsProducts.add(Product);
Seq<Product> seq = JavaConversions.asScalaBuffer(dataFeedsProducts).seq();

fooWithProducts(seq)

// SCALA helpers

public class Conversions {
    //https://stackoverflow.com/questions/11903167/convert-java-util-hashmap-to-scala-collection-immutable-map-in-java/11903737#11903737
    @SuppressWarnings("unchecked")
    /**
     * Transforms a java map to a scala immutable map
     */
    public static <K, V> scala.collection.immutable.Map<K, V> toScalaImmutableMap(java.util.Map<K, V> javaMap) {
        final java.util.List<scala.Tuple2<K, V>> list = new java.util.ArrayList(javaMap.size());
        for (final java.util.Map.Entry<K, V> entry : javaMap.entrySet()) {
            list.add(scala.Tuple2.apply(entry.getKey(), entry.getValue()));
        }
        final scala.collection.Seq<Tuple2<K, V>> seq = scala.collection.JavaConverters.asScalaBufferConverter(list).asScala().toSeq();
        return (scala.collection.immutable.Map<K, V>) scala.collection.immutable.Map$.MODULE$.apply(seq);
    }

    /**
     * transforms a scala map to the java counterpart
     */
    public static <K,V> java.util.Map<K,V> mapAsJavaMap(scala.collection.immutable.Map<K,V> m) {
        if (m == null) {
            return null;
        }
        return JavaConversions.mapAsJavaMap(m);
    }

    public static<A> Seq<A> asScalaSeq(java.util.List<A> l) {
        return JavaConversions.asScalaBuffer(l).toSeq();
    }
}
//JAVA
//创建产品
HashMap attributes=新的HashMap();
属性。放置(“我的属性”、“我的价值”);
//创建scala集合
scala.collection.immutable.Map scalaAttributes=Conversions.toScalaImmutableMap(属性);
//创建产品
产品p=产品(“id”、“组”、ScalaAttribute)
//创建产品的scala序列
ArrayList dataFeedsProducts=新的ArrayList();
dataFeedsProducts.add(产品);
Seq-Seq=JavaConversions.asScalaBuffer(dataFeedsProducts.Seq();
食品产品(续)
//SCALA助手
公共类转换{
//https://stackoverflow.com/questions/11903167/convert-java-util-hashmap-to-scala-collection-immutable-map-in-java/11903737#11903737
@抑制警告(“未选中”)
/**
*将java映射转换为scala不可变映射
*/
公共静态scala.collection.immutable.Map toScalaImmutableMap(java.util.Map javaMap){
final java.util.List List=new java.util.ArrayList(javaMap.size());
for(最终的java.util.Map.Entry条目:javaMap.entrySet()){
添加(scala.Tuple2.apply(entry.getKey(),entry.getValue());
}
final scala.collection.Seq Seq=scala.collection.JavaConverters.asScalaBufferConverter(list.asScala().toSeq();
返回(scala.collection.immutable.Map)scala.collection.immutable.Map$.MODULE$.apply(seq);
}
/**
*将scala映射转换为java对应映射
*/
public static java.util.Map mapAsJavaMap(scala.collection.immutable.Map m){
如果(m==null){
返回null;
}
返回JavaConversions.mapAsJavaMap(m);
}
公共静态Seq asScalaSeq(java.util.List l){
返回JavaConversions.asScalaBuffer(l.toSeq();
}
}

我们想知道是否有一种方法可以为这些Scala习惯用法注释Scala代码或自动生成等效的Java对应接口。

大多数用Scala编写但应该同时从Scala和Java使用的框架都有一个单独的Java API。例如,Akka、Play和Spark就是这样

这并不是因为从Java实例化Scala类是完全不可能的,而是因为它非常不惯用、繁琐和烦人。因此,设计师没有将Java数据结构转换为Scala数据结构的负担转移给API的用户,而是简单地创建一个单独的Java API,并一次性解决所有转换和工厂方法的问题

也就是说,而不是

  • 在Scala中编写库并仅提供Scala API
  • 用Java编写C_1类,使用Scala API,用转换污染代码(痛苦-1)
  • 用Java编写类C\u n,使用Scala API,用转换污染代码(痛苦-n)
您可以执行以下操作:

  • 在Scala中编写一个库,首先提供Scala API
  • foobar.api.java
    包添加到您的库中,实现一个单独的JavaAPI,仍然使用Scala(pain singleton)
  • 用Java API编写C_1类(nice-and-pleaster-1)
  • 使用Java API编写类C_n(nice-and-pleaster-n)
这将大大减少您对scala库用户造成的总体痛苦(在您的情况下:您自己)

对于您提供的小代码段,这具体意味着:

1) 提供工厂方法,以便方便地从Java实例化
产品
s:

// somewhere in api.java
def product(
  id: String, 
  grp: String, 
  attrToVal: java.util.HashMap[String, String]
): Product = /* use `JavaConversions`, invoke constructor */
2) 提供可从Java调用的
fooWithProducts
版本 没有任何转换:

// in api.java
def fooWithProducts(ps: java.util.List[Product]): Foo = 
  // Convert java List to scala Seq here, 
  // call original `fooWithProducts`

对API中应该出现的每个类和方法都这样做。要使其正常工作,API必须具有最小的表面积,并且与库的内部结构相比,API必须集中且相对简单。

您看到了吗?@LucaT。您所链接的内容似乎更适合java->scala方向,因为scala有隐式转换,所以这就不那么痛苦了。
// in api.java
def fooWithProducts(ps: java.util.List[Product]): Foo = 
  // Convert java List to scala Seq here, 
  // call original `fooWithProducts`