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

摘要: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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,417评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,921评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,850评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,945评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,069评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,188评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,239评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,994评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,409评论 1 304
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,735评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,898评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,578评论 4 336
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,205评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,916评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,156评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,722评论 2 363
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,781评论 2 351