Java和Scala集合間的相互轉(zhuǎn)換方式
Java和Scala集合間的相互轉(zhuǎn)換
在scala中,調(diào)用一個(gè)java的方法,通常需要傳遞相應(yīng)的參數(shù)。下面是scala與java互轉(zhuǎn)換對(duì)應(yīng)表
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
scala與java互轉(zhuǎn)
import collection.JavaConverters._ import collection.mutable._ val map = Map("k" -> "v") //轉(zhuǎn)換成java val javaMap = map.asJava //轉(zhuǎn)換成 scala javaMap.asScala
注:在Scala內(nèi)部,這些轉(zhuǎn)換是通過(guò)一系列“包裝”對(duì)象完成的,這些對(duì)象會(huì)將相應(yīng)的方法調(diào)用轉(zhuǎn)發(fā)至底層的容器對(duì)象。所以容器不會(huì)在Java和Scala之間拷貝來(lái)拷貝去。
一個(gè)值得注意的特性是,如果你將一個(gè)Java容器轉(zhuǎn)換成其對(duì)應(yīng)的Scala容器,然后再將其轉(zhuǎn)換回同樣的Java容器,最終得到的是一個(gè)和一開(kāi)始完全相同的容器對(duì)象(譯注:這里的相同意味著這兩個(gè)對(duì)象實(shí)際上是指向同一片內(nèi)存區(qū)域的引用,容器轉(zhuǎn)換過(guò)程中沒(méi)有任何的拷貝發(fā)生)
有一些Scala容器類(lèi)型可以轉(zhuǎn)換成對(duì)應(yīng)的Java類(lèi)型,但是并沒(méi)有將相應(yīng)的Java類(lèi)型轉(zhuǎn)換成Scala類(lèi)型的能力
Seq => java.util.List mutable.Seq => java.util.List Set => java.util.Set Map => java.util.Map
因?yàn)镴ava并未區(qū)分可變?nèi)萜鞑豢勺內(nèi)萜黝?lèi)型,所以,雖然能將scala.immutable.List轉(zhuǎn)換成java.util.List,但所有的修改操作都會(huì)拋出“UnsupportedOperationException”
scala> 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:131)
Java與Scala的集合對(duì)比
一、Java集合
面向?qū)ο笳Z(yǔ)言對(duì)事物的體現(xiàn)是以對(duì)象的形式,為了對(duì)多個(gè)對(duì)象進(jìn)行存儲(chǔ)。單單靠數(shù)組不足以解決問(wèn)題,同時(shí)對(duì)對(duì)象的操作極為的不方便。數(shù)組不可以存儲(chǔ)不同的多個(gè)對(duì)象。
集合就像是一個(gè)容器,可以動(dòng)態(tài)的把多個(gè)對(duì)象的引用放入到容器中。
Collection集合:不按照添加的順序存放對(duì)象的集合,集合內(nèi)元素的內(nèi)容是可以重復(fù)的。
保存一個(gè)一個(gè)的對(duì)象
1、Collection=>Set接口
元素不按照添加的順序(無(wú)序)、不可重復(fù)添加相同元素(內(nèi)容而不是地址)的集合
>HashSet
使用哈希算法實(shí)現(xiàn)的Set集合
去重規(guī)則:兩個(gè)對(duì)象的equals為true,并且兩個(gè)對(duì)象的哈希碼相等
如果想讓自定義對(duì)象重復(fù),需要重寫(xiě)equals和hashCode
>LinkedSet
>TreeSet
添加的順序是無(wú)序的,且不可重復(fù)
注意添加元素的時(shí)候不能添加不同的類(lèi)型,因?yàn)闀?huì)進(jìn)行比較,不同類(lèi)型的元素?zé)o法進(jìn)行比較
1、自定義類(lèi)要實(shí)現(xiàn)Comparable接口,實(shí)現(xiàn)并重寫(xiě)方法。
去重規(guī)則:compareTo返回0
2、寫(xiě)一個(gè)具體類(lèi),讓這個(gè)類(lèi)實(shí)現(xiàn)Comparator接口,重寫(xiě)compare方法,讓比較器關(guān)聯(lián)到TreeSet中
使用樹(shù)實(shí)現(xiàn)的Set集合,底層是通過(guò)二叉樹(shù)實(shí)現(xiàn)的(=> 所以添加的數(shù)據(jù),遍歷出來(lái)后是看起來(lái)有順序的)
2、Collection=>List接口
元素按照添加的順序(有序)、可重復(fù)添加相同元素的集合
>ArrayList
使用數(shù)組實(shí)現(xiàn)的List集合
>LinkedList
使用鏈表實(shí)現(xiàn)的List集合
>Vector
- Vector:是線程安全的動(dòng)態(tài)數(shù)組,底層是數(shù)組結(jié)構(gòu),初始化為長(zhǎng)度為10的數(shù)組,如果容量滿了,按照2.0倍擴(kuò)容。除了支持foreach和Iterator遍歷,還支持Enumeration迭代。
ArrayList和LinkedList
1.ArrayList是實(shí)現(xiàn)了基于動(dòng)態(tài)數(shù)組的數(shù)據(jù)結(jié)構(gòu),LinkedList基于鏈表的數(shù)據(jù)結(jié)構(gòu)。
2.對(duì)于隨機(jī)訪問(wèn)get和set,ArrayList覺(jué)得優(yōu)于LinkedList,因?yàn)長(zhǎng)inkedList要移動(dòng)指針。
3.對(duì)于新增和刪除操作add和remove,LinedList比較占優(yōu)勢(shì),因?yàn)锳rrayList要移動(dòng)數(shù)據(jù)。 這一點(diǎn)要看實(shí)際情況的。若只對(duì)單條數(shù)據(jù)插入或刪除,ArrayList的速度反而優(yōu)于LinkedList。但若是批量隨機(jī)的插入刪除數(shù)據(jù),LinkedList的速度大大優(yōu)于ArrayList. 因?yàn)锳rrayList每插入一條數(shù)據(jù),要移動(dòng)插入點(diǎn)及之后的所有數(shù)據(jù)。
Arraylist,LinkedList,Vector的區(qū)別
- ArrayList:是線程不安全的動(dòng)態(tài)數(shù)組,底層是數(shù)組結(jié)構(gòu),JDK1.7后初始化為空數(shù)組,在添加第一個(gè)元素時(shí)初始化為長(zhǎng)度為10的數(shù)組,如果容量滿了,按照1.5倍擴(kuò)容。支持foreach和Iterator遍歷。
- Vector:是線程安全的動(dòng)態(tài)數(shù)組,底層是數(shù)組結(jié)構(gòu),初始化為長(zhǎng)度為10的數(shù)組,如果容量滿了,按照2.0倍擴(kuò)容。除了支持foreach和Iterator遍歷,還支持Enumeration迭代。
- LinkedList:是雙向鏈表,底層是鏈表結(jié)構(gòu)。當(dāng)頻繁在集合中插入、刪除元素時(shí),效率較高,但是查找遍歷的效率較低。
3、Map接口
Map集合:保存一對(duì)一對(duì)的對(duì)象
具有映射關(guān)系“Key-Value”形式的集合
1、Map中的key和value都可以是任何引用類(lèi)型的數(shù)據(jù)
2、Map中的key是用set來(lái)進(jìn)行存放的,不允許重復(fù),也就是說(shuō)同一個(gè)Map對(duì)象所對(duì)應(yīng)的類(lèi),需要重寫(xiě)hashCode和equals方法
3、Map中的key和value存在單向一一對(duì)應(yīng)關(guān)系,通過(guò)指定的key,可以唯一確定value的值
Map是如何維護(hù)k-v的呢?
- Entry:橫向來(lái)看,條目對(duì)象里面是一個(gè)一個(gè)的鍵值對(duì),若干個(gè)Entry構(gòu)成一個(gè)Map(無(wú)序不可重復(fù))EntrySet
縱向來(lái)看KeySet專門(mén)放鍵,Collection放值
>HashMap
HashMap是線程不安全的哈希表,底層結(jié)構(gòu)是JDK1.7時(shí)數(shù)組+鏈表,JDK1.8時(shí)數(shù)組+鏈表/紅黑樹(shù)。
HashMap的線程安全問(wèn)題可以使用Collections的synchronizedMap(Map<K,V> m) 方法解決。
>TreeMap
> Hashtable
Hashtable是線程安全的哈希表,底層結(jié)構(gòu)是數(shù)組+鏈表。
二、Scala集合
>1、Scala集合有三個(gè)大類(lèi):序列Seq、集Set、映射Map。并且所有的集合都有自己擴(kuò)展的特質(zhì)
>2、對(duì)于幾乎所有的集合類(lèi),Scala都同時(shí)提供了可變與不可變兩個(gè)版本,位于兩個(gè)包下
不可變集合:scala.collection.immutable
不可變集合指的是,該集合的對(duì)象不能修改,每次修改過(guò)后,就會(huì)產(chǎn)生新的對(duì)象。這里修改指的是長(zhǎng)度的改變,增加或減少。當(dāng)只是修改對(duì)象里面的屬性時(shí),是可以的。
可變集合:scala.collection.immutable
可變集合指的是,可以對(duì)原對(duì)象修改,并且不會(huì)產(chǎn)生新的對(duì)象。
常用 ==>
1、Seq
不可變:~
–>IndexedSeq
Array,String ->底層隱式轉(zhuǎn)化
–>LinearSeq
List,Queue,Stack
可變:~
- ArrayBuffer
- StringBuffer
2、Set
默認(rèn)情況下,Set使用的是不可變集合,如果想要使用可變的集合,需要導(dǎo)包–scala.collection.mutable.Set
無(wú)序,且數(shù)據(jù)不可重復(fù)
3、Map
創(chuàng)建Map,默認(rèn)是不可改變的。
使用可變的時(shí)候,和Java的一樣。
值得注意的是:
根據(jù)key,獲取value值有兩種情況~
1.獲取到value
2.沒(méi)有獲取到,返回空
與java不同的是,Scala沒(méi)有類(lèi)似于Java直接獲?。╣et())方法,Scala為了避免取到null值,添加了新的類(lèi)型Option
Option下有兩個(gè)子類(lèi) None | Some – None相當(dāng)于沒(méi)獲取到值,Some會(huì)對(duì)獲取到的value進(jìn)行包裝處理
如果返回None,可以進(jìn)行二次處理,給一個(gè)默認(rèn)值
如果真的想通過(guò)key來(lái)獲取Value可以使用getOrElse(elem,default) 函數(shù)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- IDEA中scala生成變量后自動(dòng)顯示變量類(lèi)型問(wèn)題
- Idea中添加Maven項(xiàng)目支持scala的詳細(xì)步驟
- Scala數(shù)據(jù)庫(kù)連接池的簡(jiǎn)單實(shí)現(xiàn)
- C# ExecuteScalar()方法案例講解
- idea中如何創(chuàng)建scala項(xiàng)目
- Scala函數(shù)式編程專題--scala集合和函數(shù)
- Scala函數(shù)式編程專題--scala基礎(chǔ)語(yǔ)法介紹
- Scala入門(mén)教程詳解
- scala中常用特殊符號(hào)詳解
- Scala基礎(chǔ)語(yǔ)法總結(jié)
相關(guān)文章
Spring Cloud 服務(wù)網(wǎng)關(guān)Zuul的實(shí)現(xiàn)
這篇文章主要介紹了Spring Cloud 服務(wù)網(wǎng)關(guān)Zuul的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07Spring實(shí)戰(zhàn)之Bean定義中的SpEL表達(dá)式語(yǔ)言支持操作示例
這篇文章主要介紹了Spring實(shí)戰(zhàn)之Bean定義中的SpEL表達(dá)式語(yǔ)言支持操作,結(jié)合實(shí)例形式分析了Bean定義中的SpEL表達(dá)式語(yǔ)言操作步驟與實(shí)現(xiàn)技巧,需要的朋友可以參考下2019-12-12Java線程的生命周期命名與獲取代碼實(shí)現(xiàn)
這篇文章主要介紹了Java線程的生命周期命名與獲取代碼實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04Java日常練習(xí)題,每天進(jìn)步一點(diǎn)點(diǎn)(51)
下面小編就為大家?guī)?lái)一篇Java基礎(chǔ)的幾道練習(xí)題(分享)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧,希望可以幫到你2021-08-08Java實(shí)現(xiàn)圖章或簽名插在pdf的固定位置
使用Java技術(shù)在word轉(zhuǎn)換成pdf過(guò)程中實(shí)現(xiàn)將圖章或者簽名插入在pdf中,并生成帶圖章或者簽名的pdf,來(lái)完成某些特定場(chǎng)景的需求,文中有詳細(xì)的代碼示例,需要的朋友可以參考下2023-10-10Springboot為什么加載不上application.yml的配置文件
這篇文章主要介紹了Springboot為什么加載不上application.yml的配置文件,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-10-10java實(shí)現(xiàn)身份證號(hào)碼驗(yàn)證的示例代碼
這篇文章主要為大家詳細(xì)介紹了如何利用java語(yǔ)言實(shí)現(xiàn)身份證號(hào)碼驗(yàn)證的功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-09-09Java?CopyOnWriteArrayList源碼超詳細(xì)分析
為了將讀取的性能發(fā)揮到極致,jdk中提供了CopyOnWriteArrayList類(lèi),下面這篇文章主要給大家介紹了關(guān)于java中CopyOnWriteArrayList源碼解析的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-11-11