java集合简介 ArrayList 扩容 Iterator List、ArrayList、LinkedList 装箱和取消装箱 总结
集合简介
Java容器类库的用途是“保存对象”:collection接口是集合类的根接口,Java中没有提供这个接口的直接实现类,但是让其被继承产生了两个接口,
set和list,set不能包含重复的元素,list是一个有序集合,可以包含重复的元素,提供了按索引访问的方式;
Collection,一个独立的元素序列,这些元素都服从一条或者多条规则,List必须按照插入顺序保存元素,而Set不能有重复的元素,Queue按照排队
规则来确定对象产生的顺序(通常与他插入的顺序相同);
ArrayList:
ArrayList是命名空间System.Collection下的一部分,在使用该类的时候必须进行引用,同时继承IList接口,提供了数据存储和检索;
初始化
ArrayList初始化 三种:
1、不初始化起始容量,ArrayList a = new ArrayList();默认容量为0;当数组容量满,会自动扩容为两倍;(ArrayList的对象大小是按照其中存储
的数据来动态扩充和收缩的,所以在声明ArrayList对象时可不指定长度)
2、指定初始化容量;
3、以一个集合或者数组初始化 ArrayList a =newArrayList(a1);a1为集合或者数组;
附:(创建:List<Apple> apples = new ArrayList<Apple>();ArrayList已经被向上转型为List,LinkList具有在List接口中未包含的额外方法,
TreeMap也具有在Map中未包含的额外方法;如果需要使用这些方法就不能向上转型;(具体方法待查))
存取
修改数据:list[2]=123;
插入数据:list.Insert(0,"***");
在ArrayList中插入不同类型的数据是合法的,因为ArrayList会吧所有插入其中的数据当做object类型出来,但是在使用ArrayList处理数据时,会报
类型不匹配的错误,说明ArrayList不是类型安全的,在存储和检索值类型时通常发生装箱和取消装箱操作,带来很大的性能消耗(关于装箱和拆箱见下文);
ArrayList允许你使用数字来查找值,某种意义上,将数字与对象关联在一起,映射表允许我们使用另一个对象来查找某个对象,他被称为“关联数组”,
因为它将某些对象关联在一起,或者称为“字典”,唯一需要指定所使用的精确类型的地方就是在创建的时候;
数组扩容:
对ArrayList效率影响比较大的一个因素:每当执行add、addrange、insertrange等添加元素的方法,就会检查内部数组的容量是否不够,如果是,
就会以当前容量的两倍来构建一个数组,将旧元素copy到新的数组中,然后丢弃旧数组,在这个临界点的扩容操作,比较影响效率;ArrayList的初始化大
小容量是4;所以正确预估可能的元素,并且在适当的时候调用TrimSize方法是提高ArrayList使用效率的重要途径;(TrimSize方法,用这个方法将
ArrayList固定到实际元素的大小,当动态数组元素确定补在添加的时候,可以调用这个方法来释放空余内存;ToArray方法,将ArrayList元素
copy到新数组;)
Iterator
所有集合类,都实现了Iterator接口,这是一个用于遍历集合中元素的接口,主要包含三种方法:
hasNext():是否还有下一个
next():返回下一个
remove()删除当前元素;
如:`Iterator<Integer> iterator = set.iterator();
//Set set...
while(iterator.hasNext()){
System.out.print(iterator.next());//
}`
关于遍历:在类集合中提供以下四种常见输出方式:
Iterator;迭代输出,使用最多;
ListIterator:是Iterator的子接口,专门用于输出List中的内容;
foreach:jdk1.5后新功能,输出数组和集合;如:
for (int n : array) {
System.out.println(n);
}
for循环;
List、ArrayList、LinkedList
List:因为ArrayList存在不安全类型和封箱拆箱的缺点,所以出现了泛型的概念,List类是ArrayList类的泛型等效类,大部分用法都与ArrayList类似,
因为List类也继承了IList接口,关键的区别在于,声明List集合时,需要为其声明List集合内数据的对象类型;
LinkedList:数组和数组列表都有一个重大缺陷,那就是从数组中间位置删除一个元素需要付出很大代价,因为数组中出于被删除元素之后的所有元素
都要向数组的前端移动,数组中插入也是;链表将每个对象存放在独立的节点中,每个节点还存放序列中上一个节点的引用和下一个节点的引用,这样对
插入和删除,只需要更新附近节点就行;数组容量是固定的,只能一次获取或者设置一个元素的值,而ArrayList或者List<T>的容量可根据需要自动
扩充,修改、删除或者插入;数组可以具有多个维度,ArrayList和List<T>始终只有一个维度,但是可以轻松创建数组列表或者列表的列表,特定
类型object除外的数组的的性能优于ArrayList的性能,因为ArrayList
属于object类型,存在存储或检索索引值类型时通常发生装箱和取消装箱操作,不过,在不需要重新分配时,即最初的容量十分接近列表的最大容量,
List<T>的性能与同类型的数组十分接近;在决定使用List<T>还是ArrayList时,List<T>类在大多数情况向执行的更好并且是类型安全的,
如果对List<T>类的类型T使用引用类型,那两个类的行为是完全相同的,但是对T使用值类型,则需要考虑实现装箱问题;
ArrayList实现基于动态数组的数据结构,LinkedList基于链表的数据结构;对于随机访问get和set,ArrayList优于后者,后者需要移动指针;
对于增加删除add、remove,后者占优,前者需要移动数据;
装箱和拆箱
Java为每种基本数据类型都提供了对应的包装器类型,Javase 5 开始提供了自动装箱特性,比如要生成一个的10的integer对象,
Integer i= new Integer(10);但是现在只需要Integer i= 10;这个过程会自动根据数值创建对应的Integer对象,这就是装箱,反之,拆箱 与
装箱对应,自动将包装器类型转化为基本数据类型;int n = i;
装箱:自动将基本数据类型转换为包装器类型;
拆箱:就是自动将包装器类型转换为基本数据类型;
或者说装箱是值类型到object类型或者到此值类型所实现的任何接口类型的隐式转换,对值类型装箱会在堆中分配一个对象实例,并将该值复制到新的
对象中,拆箱,是从object类型到值类型或从接口类型到实现该接口的值类型的显式转换;装箱过程是调用包装器的valueOf()方法实现,拆箱则是调
用包装器的XXXValue方法实现;== 运算符的两个操作数都是包装器类型的引用,则比较指向的是否是同一个对象,如果其中有一个操作数是表达式,包
含算术运算,则比较的是数值(会触发自动拆箱),另外,对于包装器类型,equals方法并不会进行类型转化;
总结
Java的集合类主要使用的和核心是hash,其中hashmap和hashtable等下一文再写,这里只是根据接触Java的历程小小总结一下;
如有错误或者觉得摘抄而未指明出处的地方欢迎指正(⊙﹏⊙)b。