集合与数组详解
⼀、数组与集合的基础介绍:
1.数组
(1)同⼀组数据类型的集合,其实数组就是⼀个容器。
(2)数组的好处在于可以对内部元素从0开始进⾏索引编号,⽅便对内部元素进⾏操作。
(3)数组的声明:
int[ ] name=new int[ X ];
int为声明数组所存储的元素类型,name为声明数组的名称,x为数组所包含具体⼏个元素;
另外还可以⽤以下⽅式声明数组:
int[ ] name=new int[ ]{元素1,元素2 };
int[ ] name={ 元素1,元素2 };
这样声明数组还将数组内具体元素都进⾏了表⽰。
(4)数组的具体操作
数组最常⽤的操作就是通过索引取元素
name[ index ],name为数组名称,index为索引,要牢记数组是固定长度固定类型的容器。
2.集合
(1)集合存放于java.util包中,集合类中存放的都是对象的引⽤并没有存放具体的对象内容,我们称集合中的对象就是指对象的引⽤,集合中主要包含三类接
⼝,Set(集)、List(列表)、Map(映射)。
Collection接⼝是集合类的根接⼝,Java中没有提供这个接⼝的直接的实现类。但是却让其被继承产⽣了两个接⼝,就是Set和List。Set中不能包含重复的元素。List是⼀个有序的集合,可以包含重复的元素,提供了按索引访问的⽅式。
Map是Java.util包中的另⼀个接⼝,它和Collection接⼝没有关系,是相互独⽴的,但是都属于集合类的⼀部分。Map包含了key-value对。Map不能包含重复的key,但是可以包含相同的value。
Iterator,所有的集合类,都实现了Iterator接⼝,这是⼀个⽤于遍历集合中元素的接⼝,主要包含以下三种⽅法:
<1>hasNext()是否还有下⼀个元素。
<2>next()返回下⼀个元素。
<3>remove()删除当前元素。
Iterator遍历数组举例:
ArrayList al = new ArrayList();
Iterator iter= al.iterator();
while(iter.hasNext()){
System.out.());
}
(2)下图详细介绍了集合类的接⼝,及接⼝实现类集合的特点:
indexof能用于数组吗 <1>List(有序、可重复):List⾥存放的对象是有序的,同时也是可以重复的,List关注的是索引,拥有⼀系列和索引相关的⽅法,查询速度快。因为往list集合⾥插⼊或删除数据时,会伴随着后⾯数据的移动,所以插⼊删除数据速度慢。
实现List接⼝的类主要有ArrayList,Vector,LinkedList,其存储性能和特性如下:
ArrayList和Vector都是使⽤数组⽅式存储数据,此数组元素数⼤于实际存储的数据以便增加和插⼊元素,它们都允许直接按序号索引元素,但是插⼊元素要涉及数组元素移动等内存操作,所以索引数据快⽽插⼊数据慢,Vector由于使⽤了 synchronized⽅法(线程安全),通常性能上较ArrayList差,因此现在vector基本被ArrayList取代,⽽LinkedList使⽤双向链表实现存储,按序号索引数据需要进⾏前向或后向遍历,但是插⼊数据时只需要记录本项的前后项即可,所以插⼊速度较快。
需要注意的是:
1.对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。
2.对于新增和删除操作add和remove,LinedList⽐较占优势,因为ArrayList要移动数据。
3.查操作indexOf,lastIndexOf,contains等,两者差不多。
List集合中常⽤的操作:
增 add(Object) 添加⼀个Object元素;
删 remove(index) 删除给定索引的元素;
查 get(index) 获取给定索引的元素;
改 set(index, Object) 修改给定索引的元素为Object;
<2>Set(⽆序、不能重复):Set集合的基本特征是不记录添加顺序,不允许元素重复,只是简单地把对象加⼊集合中,最常⽤的实现类是HashSet。
1.HashSet类直接实现了Set接⼝,其底层其实是包装了⼀个HashMap去实现的。HashSet采⽤HashCode算法来存取集合中的元素,因此具有⽐较好的读取和查性能。
主要特征:
不仅不能保证元素插⼊的顺序,⽽且在元素在以后的顺序中也可能变化(这是由HashSet按HashCode存储对象(元素)决定的,对象变化则可能导致HashCode变化);
HashSet是线程⾮安全的;
HashSet元素值可以为NULL;
2.TreeSet底层数据结构为⼆叉树,是⼀个有序的set集合,是线程不安全的;
3.LinkedHashSet是HashSet的⼀个⼦类,LinkedHashSet也根据HashCode的值来决定元素的存储位置,但同时它还⽤⼀个链表来维护元素的插⼊顺序,插⼊的时候即要计算hashCode⼜要维护链表,⽽遍历的时候只需要按链表来访问元素。
需要注意的是:
HashSet和TreeSet是Set集合中⽤得最多的集合。HashSet总是⽐TreeSet集合性能好,因为HashSet不需要额外维护元素的顺序。
LinkedHashSet需要⽤额外的链表维护元素的插⼊顺序,因此在插⼊时性能⽐HashSet低,但在迭代访问(遍历)时性能更⾼。因为插⼊的时候即要计算hashCode⼜要维护链表,⽽遍历的时候只需要按链表来访问元素。
Set集合中常⽤的操作:
增 add(Object) 往set中添加元素使⽤的是add()⽅法,但是在set中没有add(index , element)⽅法;
删 remove(Object) 删除具体的Object元素;
查(⽆此⽅法)
改(需要⾃⼰写⼯具类)如下:
public Set<Object> updateSetValue(Set<Object> oldSet) {
Set<Object> newSet = new HashSet<Object>();
for (Object s : oldSet) {
if (s != "你要修改前的值") {
newSet.add(s);
} else {
newSet.add("你要修改后的值");
}
}
return newSet;
}
<3>Map(键值对、键唯⼀、值不唯⼀):Map集合中存储的是键值对,键不能重复,值可以重复。根据键得到值,对map集合遍历时先得到键的set集合,对set集合进⾏遍历,得到相应的值。HashMap为常⽤的实现类。
实现类:HashMap、Hashtable、LinkedHashMap和TreeMap
1.HashMap (底层数据结构哈希表)
HashMap是最常⽤的Map,它根据键的HashCode值存储数据,根据键可以直接获取它的值,具有很快的访问速度,遍历时,取得数据的顺序是完全随机的。因为键对象不可以重复,所以HashMap最多只允许⼀条记录的键为Null,允许多条记录
的值为Null,是⾮同步的(⾮同步就是线程不安全)
2.Hashtable (底层数据结构哈希表)
Hashtable与HashMap类似,是HashMap的线程安全版,它⽀持线程的同步,即任⼀时刻只有⼀个线程能写Hashtable,因此也导致了Hashtale在写⼊时会⽐较慢,它继承⾃Dictionary类,不同的是它不允许记录的键或者值为null,同时效率较低。
3.ConcurrentHashMap(不常使⽤)
线程安全,并且锁分离。ConcurrentHashMap内部使⽤段(Segment)来表⽰这些不同的部分,每个段其实就是⼀个⼩的hash table,它们有⾃⼰的锁。只要多个修改操作发⽣在不同的段上,它们就可以并发进⾏。
4.LinkedHashMap(不常使⽤)
LinkedHashMap保存了记录的插⼊顺序,在⽤Iteraor遍历LinkedHashMap时,先得到的记录肯定是先插⼊的,在遍历的时候会⽐HashMap慢,有HashMap的全部特性。
5.TreeMap(底层数据结构⼆叉树)
TreeMap实现SortMap接⼝,能够把它保存的记录根据键排序,默认是按键值的升序排序(⾃然顺序),也可以指定排序的⽐较器,当⽤Iterator遍历TreeMap时,得到的记录是排过序的。不允许key值为空,⾮同步的;
Map集合中常⽤的操作:
添加 put(key,value):当存储的键相同时,新的值会替换⽼的值,并将⽼值返回。如果键没有重复,返回null。
删除 clear():清空
remove(key) :删除指定键。
判断 boolean isEmpty():
boolean containsKey(key):是否包含key
boolean containsValue(value) :是否包含value
取出 int size():返回长度
get(key) :通过指定键获取对应的值。如果返回null,可以判断该键不存在。当然有特殊情况,就是在hashmap集合中,是可以存储null键null 值的。
Collection values():获取map集合中的所有的值。
map元素的遍历:
HashMap map = new HashMap();
map.put("ZH", "中国");
map.put("EN", "英国");
map.put("ZH1", "中华⼈名共和国");
Set<Map.Entry<String,String>> set = Set();
for (Entry<String, String> entry : set) {
System.out.Key()+"----");
System.out.Value());
}
输出结果:
EN----英国
ZH----中国
ZH1----中华⼈名共和国
⼆、数组与集合的区别:
1、数组声明了它容纳的元素的类型,⽽集合不声明。
2、数组是静态的,⼀个数组实例具有固定的⼤⼩,⼀旦创建了就⽆法改变容量了。⽽集合是可以动态扩展容量,可以根据需要动态改变⼤⼩,集合提供更多的成员⽅法,能满⾜更多的需求。
3、数组不论是效率还是类型检查都是最好的。
4、数组的存放的类型只能是⼀种,集合存放的类型可以不是⼀种(不加泛型时添加的类型是Object);
5、数组是java语⾔中内置的数据类型,是线性排列的,执⾏效率或者类型检查,都是最快的,ArrayList就是基于数组创建的容器类。
6、数组最⼤的弱点就是功能太弱⼩,所有才会有其他容器的出现。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论