美文网首页Scala学习Java学习
Java与Scala集合互转,Java中调用Scala集合,Sc

Java与Scala集合互转,Java中调用Scala集合,Sc

作者: xiaogp | 来源:发表于2020-08-19 15:49 被阅读0次

摘要:ScalaJavaJavaConverters
包括三种场景的转化

  • Java脚本中,将Scala集合转化为Java集合
  • Scala脚本中,将Scala集合转化为Java集合
  • Scala脚本中,将Java集合转化为Scala集合

JavaConverters隐式转换

Scala提供了大量的方法来隐式转换所有主要的Java和Scala容器类型。其中提供了如下的双向类型转换

Iterator <=> java.util.Iterator
Iterator <=> java.util.Enumeration
Iterable <=> java.lang.Iterable
Iterable <=> java.util.Collection
mutable.Buffer <=> java.util.List
mutable.Set <=> java.util.Set
mutable.Map <=> java.util.Map
mutable.ConcurrentMap <=> java.util.concurrent.ConcurrentMap

使用这些转换很简单,只需从JavaConverters对象中import它们即可。import之后,通过扩展方法 asScala 和 asJava 就可以在Scala容器和与之对应的Java容器之间进行隐式转换了

scala> import collection.JavaConverters._
import collection.JavaConverters._

还有一些Scala容器类型可以转换成对应的Java类型,但是并没有将相应的Java类型转换成Scala类型的能力,它们是:

Seq => java.util.List
mutable.Seq => java.util.List
Set => java.util.Set
Map => java.util.Map

因为Java并未区分可变容器不可变容器类型,所以,虽然能将scala.immutable.List转换成java.util.List,但所有的修改操作都会抛出“UnsupportedOperationException”

scala> val jul = List(1, 2, 3).asJava
jul: java.util.List[Int] = [1, 2, 3]

scala> jul.add(7)
java.lang.UnsupportedOperationException
  at java.util.AbstractList.add(AbstractList.java:148)

在Java中调用使用Scala集合

Scala List => Java List

在Scala中定义方法返回List,在Java中调用得到返回值并转化为Java的list。

object ReturnScalaCollection {
  def returnList(): List[String] = {
    return List("a", "b", "c")
  }

  def returnListType(): List[Int] = {
    return List(1, 2, 3)
  }
}

Scala list调用apply方法获得下标元素,循环一遍得到Java list,如果不是String对象,Java中得到的返回值泛型是Object,通过类型强转得到对应类型

public static void main(String[] args) {
        scala.collection.immutable.List<String> res = ReturnScalaCollection.returnList();
        List<String> list = new ArrayList<>();
        for (int i = 0; i < res.size(); i ++) {
            list.add(res.apply(i));
        }
        System.out.println(list);  // [a, b, c]

        scala.collection.immutable.List<Object> res2 = ReturnScalaCollection.returnListType();
        List<Integer> list2 = new ArrayList<>();
        for (int i = 0; i < res2.size(); i ++) {
            list2.add((int) res2.apply(i));
        }
        System.out.println(list2);  // [1, 2, 3]
    }
Scala Map => Java Map

Scala转List<Tuple2<>>,使用下标访问填充到Java Map。

def returnMap(): Map[String, Int] = {
    return Map("a" -> 1, "b" -> 2)
  }
public static void main(String[] args) {
        scala.collection.immutable.Map<String, Object> res3 = ReturnScalaCollection.returnMap();
//        scala.collection.immutable.List<Tuple2<String, Object>> res3List = res3.toList();
        Map<String, Integer> map = new HashMap<>();
        for (int i = 0; i < res3.size(); i ++) {
            map.put(res3.toList().apply(i)._1(), (int) res3.toList().apply(i)._2());  // {a=1, b=2}
        }
        System.out.println(map);
    }
Scala Set => Java Set

Scala转List,Java通过下标apply获取值填充到Set。

def returnSet(): Set[String] = {
    return Set("a", "b", "a")
  }
public static void main(String[] args) {
        scala.collection.immutable.Set<String> res4 = ReturnScalaCollection.returnSet();
        Set<String> set = new HashSet<>();
        for (int i = 0; i < res4.size(); i ++) {
            System.out.println(res4.toList().apply(i));
            set.add(res4.toList().apply(i));
        }
        System.out.println(set);  // [a, b]
    }
Scala Tuple => Java

在Java中指定Tuple类型和对应泛型,如果飞String需要强转,使用_1()访问,不带()可能报null

def returnTuple(): (String, String) = {
    val a = "a"
    val b = "b"
    return (a, b)
  }

  def returnTuple2(): (Int, Boolean) = {
    val a = 1
    val b = false
    return (a, b)
  }
public static void main(String[] args) {
        scala.Tuple2<String, String> res = TupleTest.returnTuple();
        String a = res._1();  // a
        String b = res._2();  // b

        scala.Tuple2<Object, Object> res2 = TupleTest.returnTuple2();
        int aa = (int) res2._1();  // 1
        boolean bb = (boolean) res2._2();  // false
    }

在Scala中转化Java集合(scala -> Java; Java -> Scala)

分为两种情况,将Scala的集合转化为Java集合,使得可以调用Java方法;将Java集合转化为Scala集合

Scala中,将Scala的集合转化为Java集合

在Java中创建传参分别是Java List,Map,Set的方法,在Scala中创建集合调用,使用JavaConverters进行隐式转换,如果单向转 Scala => Java,Scala集合可变不可变都可以,如果要双向转Scala集合必须是mutable可变的,否则Java转Scala不报错但是不能再执行修改增加操作

import java.util

import scala.collection.mutable
import scala.collection.mutable.ListBuffer

object ScalaJavaTest {
  def JavaList2ScalaList(): Unit = {
    import scala.collection.JavaConverters._
    // scala List => java.util.List
    val a: java.util.List[String] = List("a", "b", "c").asJava
    val b: java.util.List[String] = ListBuffer("a", "b", "c").asJava
    val c: java.util.Collection[String] = List("a", "b", "c").asJava
    val f: java.util.List[String] = mutable.Buffer[String]("a", "b").asJava

    // java.util.List => scala.collection.mutable.Buffer
    val aa: scala.collection.mutable.Buffer[String] = b.asScala
    val bb: scala.collection.mutable.ListBuffer[String] = a.asScala.to[ListBuffer]
    val cc: scala.collection.immutable.List[String] = a.asScala.toList

    // java.util.ArrayList => scala
    val e = new util.ArrayList[String](util.Arrays.asList("a", "b", "c"))
    val ee: scala.collection.mutable.ListBuffer[String] = e.asScala.to[ListBuffer]
  }


  def JavaMap2ScalaMap(): Unit = {
    import scala.collection.JavaConverters._
    // scala Map => java.util.Map
    val a: java.util.Map[String, Int] = Map("a" -> 1, "b" -> 2).asJava
    val c: java.util.Map[String, Int] = mutable.HashMap[String, Int]("a" -> 1, "b" -> 2).asJava
    println(a)
    println(c)
    // java.util.Map => java.util.HashMap
    val b = new util.HashMap[String, Int](a)
    b.put("c", 3)

    // java.util.Map => scala.collection.mutable.Map
    val aa: scala.collection.mutable.Map[String, Int] = a.asScala
    println(aa.getOrElse("b", -1))
    // 报错
    //    aa.put("c", 3)
    //    println(aa)
    // 转可变Map
    val aaa = mutable.Map(aa.toSeq:_*)
    aaa.put("c", 3)
    println(aaa)
    val bb: scala.collection.mutable.Map[String, Int] = b.asScala
    bb.put("c", 3)
    println(bb)

    // java.util.HashMap => scala
    val d = new util.HashMap[String, Int]()
    d.put("a", 1)
    d.put("b", 2)
    val dd: scala.collection.mutable.Map[String, Int] = d.asScala
    dd.put("c", 3)
    println(dd)
  }

  def JavaSet2ScalaSet(): Unit = {
    import scala.collection.JavaConverters._
    // scala Set => java.util.Set
    val a: java.util.Set[String] = Set("a", "b").asJava
    println(a)
    // java.util.Set => java.util.HashSet
    val b = new util.HashSet[String](a)
    b.add("c")
    println(b)

    // java.util.Set => scala.collection.mutable.Set
    val aa: scala.collection.mutable.Set[String] = a.asScala
    println(aa)
    // 报错
    //    aa.add("c")
    //    println(aa)
    // 转可变Set
    val aaa = mutable.Set(aa.toSeq:_*)
    aaa.add("c")
    val bb: scala.collection.mutable.Set[String] = b.asScala
    bb.add("c")

  }
}

参考https://docs.scala-lang.org/zh-cn/overviews/collections/conversions-between-java-and-scala-collections.html

相关文章

网友评论

    本文标题:Java与Scala集合互转,Java中调用Scala集合,Sc

    本文链接:https://www.haomeiwen.com/subject/lutdjktx.html