Java和Scala集合间的相互转换方式
java和scala集合间的相互转换
在scala中,调用一个java的方法,通常需要传递相应的参数。下面是scala与java互转换对应表
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互转
import collection.javaconverters._ import collection.mutable._ val map = map("k" -> "v") //转换成java val javamap = map.asjava //转换成 scala javamap.asscala
注:在scala内部,这些转换是通过一系列“包装”对象完成的,这些对象会将相应的方法调用转发至底层的容器对象。所以容器不会在java和scala之间拷贝来拷贝去。
一个值得注意的特性是,如果你将一个java容器转换成其对应的scala容器,然后再将其转换回同样的java容器,最终得到的是一个和一开始完全相同的容器对象(译注:这里的相同意味着这两个对象实际上是指向同一片内存区域的引用,容器转换过程中没有任何的拷贝发生)
有一些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> 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的集合对比
一、java集合
面向对象语言对事物的体现是以对象的形式,为了对多个对象进行存储。单单靠数组不足以解决问题,同时对对象的操作极为的不方便。数组不可以存储不同的多个对象。
集合就像是一个容器,可以动态的把多个对象的引用放入到容器中。
collection集合:不按照添加的顺序存放对象的集合,集合内元素的内容是可以重复的。
保存一个一个的对象
1、collection=>set接口
元素不按照添加的顺序(无序)、不可重复添加相同元素(内容而不是地址)的集合
>hashset
使用哈希算法实现的set集合
去重规则:两个对象的equals为true,并且两个对象的哈希码相等
如果想让自定义对象重复,需要重写equals和hashcode
>linkedset
>treeset
添加的顺序是无序的,且不可重复
注意添加元素的时候不能添加不同的类型,因为会进行比较,不同类型的元素无法进行比较
1、自定义类要实现comparable接口,实现并重写方法。
去重规则:compareto返回0
2、写一个具体类,让这个类实现comparator接口,重写compare方法,让比较器关联到treeset中
使用树实现的set集合,底层是通过二叉树实现的(=> 所以添加的数据,遍历出来后是看起来有顺序的)
2、collection=>list接口
元素按照添加的顺序(有序)、可重复添加相同元素的集合
>arraylist
使用数组实现的list集合
>linkedlist
使用链表实现的list集合
>vector
- vector:是线程安全的动态数组,底层是数组结构,初始化为长度为10的数组,如果容量满了,按照2.0倍扩容。除了支持foreach和iterator遍历,还支持enumeration迭代。
arraylist和linkedlist
1.arraylist是实现了基于动态数组的数据结构,linkedlist基于链表的数据结构。
2.对于随机访问get和set,arraylist觉得优于linkedlist,因为linkedlist要移动指针。
3.对于新增和删除操作add和remove,linedlist比较占优势,因为arraylist要移动数据。 这一点要看实际情况的。若只对单条数据插入或删除,arraylist的速度反而优于linkedlist。但若是批量随机的插入删除数据,linkedlist的速度大大优于arraylist. 因为arraylist每插入一条数据,要移动插入点及之后的所有数据。
arraylist,linkedlist,vector的区别
- arraylist:是线程不安全的动态数组,底层是数组结构,jdk1.7后初始化为空数组,在添加第一个元素时初始化为长度为10的数组,如果容量满了,按照1.5倍扩容。支持foreach和iterator遍历。
- vector:是线程安全的动态数组,底层是数组结构,初始化为长度为10的数组,如果容量满了,按照2.0倍扩容。除了支持foreach和iterator遍历,还支持enumeration迭代。
- linkedlist:是双向链表,底层是链表结构。当频繁在集合中插入、删除元素时,效率较高,但是查找遍历的效率较低。
3、map接口
map集合:保存一对一对的对象
具有映射关系“key-value”形式的集合
1、map中的key和value都可以是任何引用类型的数据
2、map中的key是用set来进行存放的,不允许重复,也就是说同一个map对象所对应的类,需要重写hashcode和equals方法
3、map中的key和value存在单向一一对应关系,通过指定的key,可以唯一确定value的值
map是如何维护k-v的呢?
- entry:横向来看,条目对象里面是一个一个的键值对,若干个entry构成一个map(无序不可重复)entryset
纵向来看keyset专门放键,collection放值
>hashmap
hashmap是线程不安全的哈希表,底层结构是jdk1.7时数组+链表,jdk1.8时数组+链表/红黑树。
hashmap的线程安全问题可以使用collections的synchronizedmap(map<k,v> m) 方法解决。
>treemap
> hashtable
hashtable是线程安全的哈希表,底层结构是数组+链表。
二、scala集合
>1、scala集合有三个大类:序列seq、集set、映射map。并且所有的集合都有自己扩展的特质
>2、对于几乎所有的集合类,scala都同时提供了可变与不可变两个版本,位于两个包下
不可变集合:scala.collection.immutable
不可变集合指的是,该集合的对象不能修改,每次修改过后,就会产生新的对象。这里修改指的是长度的改变,增加或减少。当只是修改对象里面的属性时,是可以的。
可变集合:scala.collection.immutable
可变集合指的是,可以对原对象修改,并且不会产生新的对象。
常用 ==>
1、seq
不可变:~
–>indexedseq
array,string ->底层隐式转化
–>linearseq
list,queue,stack
可变:~
- arraybuffer
- stringbuffer
2、set
默认情况下,set使用的是不可变集合,如果想要使用可变的集合,需要导包–scala.collection.mutable.set
无序,且数据不可重复
3、map
创建map,默认是不可改变的。
使用可变的时候,和java的一样。
值得注意的是:
根据key,获取value值有两种情况~
1.获取到value
2.没有获取到,返回空
与java不同的是,scala没有类似于java直接获取(get())方法,scala为了避免取到null值,添加了新的类型option
option下有两个子类 none | some – none相当于没获取到值,some会对获取到的value进行包装处理
如果返回none,可以进行二次处理,给一个默认值
如果真的想通过key来获取value可以使用getorelse(elem,default) 函数
以上为个人经验,希望能给大家一个参考,也希望大家多多支持。