JAVA集合类型 (现代的变量集群)
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" >
List (接口)
特点:
a. 先后顺序敏感。LIST结构中的元素必须分出谁先谁后。
b. 能够反复....
主要用来模拟队列(queue)等生活中对先后顺序敏感的应用场景。
<1> ArrayList (以数组为基础实现)
数组在使用上较为麻烦,ArrayList是一个类。其对数组进行了2次改造。或者说在数据的基础上进行了二次开发,从使用角度克服了数组的诸多缺点。但本质上还是依靠数组机制来完毕。
ArrayList内部依赖的是一个对象数组Object[], 其有众多方法。均环绕该对象数组展开。
size() 获得arraylist中内部的实际包括元素的数量。
add() 追加到最后一个
add(index,obj) 插入数据到index所指定的下标位置
remove(index) 删除指定index位置的元素
remove(obj) 删除与该对象匹配的元素 (依靠equals匹配)
contains(obj) 查看是否存在该元素
indexOf(obj) 查看元素出现的索引位 (从头開始查)
lastIndexOf(obj) 查看元素出现的索引位 (从末尾開始查)
isEmpty() 查看arraylist是否存在有效元素
subList() 创造子List
toArray() 把List转数组
trimToSize 缩小容量到实际存在元素的数量大小。
长处:
与数组类似,随机定位速度非常快.
但在编码便捷性上大大优于数组,少写不少控制代码。
缺点:
与数组类型,插入和删除easy造成大幅波动。在元素力量超出范围的时候。也有大量的数组元素拷贝的操作发生,对系统性能有较大影响。
适用场景:
数据录入后。较为稳定,删除和插入操作较少,大多为定位查询操作
数据添加的频率间隔较长,不会持续性连续添加
适合队列等对元素的先后顺序极为敏感的数据结构。
ArrayList的遍历
1. 常规遍历法
for(int i=0;i<al.size();i++)
System.out.println(al.get(i)):
1. 集合类型专用遍历法 (jdk1.5以上版本号支持)
for(Object obj:al)
System.out.println(obj);
2. 迭代体(iterator)遍历法
Iterator itr=al.iterator();
while(itr.hasNext())
System.out.println(itr.next());
ArrayList的泛型(generic type)控制
因为ArrayList非常灵活,内部能够放置各种数据类型,导致外部程序,从ArrayList中取出一个元素,还必须慎重对其推断, 有的时候外部须要大量的各种类型的代码来针对不同的对象进行相应操作,成本高昂。 有的程序猿忘记书写了一些代码。常常会导致ClassCastException, 所以后来,人们不得不限制了ArrayList中的元素的类型,要求其内部仅仅能有一种元素。
<2> LinkedList (以链表为基础实现)
长处:
与链表类型。插入和删除性能优越,不会造成内存波动。
缺点:
与链表类似。随机定位速度慢,须要从头開始依次检索.
链表的内存消耗大
适用场景:
数据录入后。较为不稳定,有着频繁删除和插入操作,随机定位查询相对较少。
适合队列等对元素的先后顺序极为敏感的数据结构。
2. Set(接口)
特点:
1. Set是Collection接口的子接口,其继承了Collection接口中的全部抽象方法。并做了针对Set应用的方法扩展。
2. Set接口强调不可反复,但无先后顺序。
a. HashSet
依据Hash (哈希) 算法进行内存分配,对数据进行保存的集合类型,对于装入当中的元素。保存在内存的位置。用户不用关心。保存的方式肯定是高效的,这是用哈希算法保证的,但有一点,不能反复! 对于插入当中的元素。HashSet不保障其先后顺序。
HashSet怎样对插入的元素进行雷同识别?
? 理解Object.hashCode()
Object对象有一个hashCode方法,该方法是本地方法,由C语言实现,返回的是这个对象在内存中的開始地址。返回值是一个整数。
不论什么对象假设其没有重写Object的hashcode方法。那么其hashcode的值均是不同的。
? HashSet依靠hashcode的返回值来推断对象是否相等
1. 当一个对象被尝试保存入hashset的时候,hashset会先调用这个对象的hashcode方法返回一个hashcode值, hashset把该值与其内部的hashcode列表(该表保存了全部保存在hashset中的对象的hashcode值)进行比对, 假设发现没有同样,则觉得该对象在hashset中没有反复,能够接纳。
2. 假设发现对象的hashcode与列表中的一个对象雷同。那么hashset将会调用该对象的equals方法进行是否同样的终于推断。Equals觉得不同,hashset还是会接纳该对象。
Object有equals和 hashcode两个方法进行对象内容是否相等的推断操作,在普通的应用中。一般我们用equals进行推断就可以,但hashset因为其特性上须要保持不同样,所以其常常进行对象是否同样的推断,因为集合类型对性能要求非常高。而equals推断涉及到较为复杂的逻辑。成本非常高。在某种程度上会减少性能,但equals推断也是精度最高的推断。
从性能角度出发,Object还提供了轻量级的推断方法, hashcode. 因为hashcode内部仅仅是整数运算,而底层还是C的,速度非常快。
Hashcode觉得不同样。则对象为不同的对象,equals就不介入的。
Hashcode觉得同样,则交由equals做最后推断,equals结果为终于结果,能够推翻hashcode的判定结果。
Hashcode是“地方法院”, equals是“终审法庭”。
? hashcode 和equals 之间的契约
因为hashcode和equals方法之间有着主从关系,特别假设一个对象终于要与hashset打交道的时候, 就必须同一时候重写hashcode和equals方法,两个方法在重写的时候,必须保证一个约定,否则将重写失败。
契约:
1. Hashcode不同, equals一定要不同
2. Hashcode同样, equals能够不同
b. TreeSet (树结构集合)
TreeSet里头的元素是不能反复的。但会依据某种既定的规则(天然顺序)进行排序输出。
全部增加TreeSet中的对象必须实现Comparable接口。
该接口仅仅有一个方法int compartTo(obj);
返回值:
1 当前对象大于传入对象
0 当前对象等于传入对象
-1 当前对象小于传入对象