一, 集合的定义
集合: 是在计算机中用于存储一种或多种引用类型数据, 并且长度可变的容器.
外延: List 集合, Queue 集合, Set 集合
二, 各类集合的特点
List 集合(继承 Collection 接口): 有序存储可重复元素
外延: ArrayList 集合, Vector 集合, LinkedList 集合
ArrayList 集合: 基于数组实现, 长度可变的, 分配连续内存空间的 List 集合. 特点: 线程异步, 线程不安全, 效率高 遍历以及随机访问元素的效率高
Vector 集合: 基于数组实现的, 线程同步的遗留集合类. 特点: 线程同步的, 多线程安全的, 效率低
LinkedList 集合: 采用链表存储方式, 实现了 List 接口和 Queue 接口的集合. 插入, 删除元素效率比较高
LinkedList 实现了 List,Deque,Queue 接口
List 集合实现类的使用场合:
要求快速访问元素, 则使用 ArrayList 集合.
要求快速插入和删除元素, 则使用 LinkedList 集合.
当对多线程元素操作时, 则使用 Vector 集合.
要求数据先进后出时, 则使用 Stack 集合类.
Queue 集合(继承 Collection 接口)(队列 先进先出): 用于存储可重复元素的, 先进先出的集合.(只允许在表的前端进行删除操作, 而在表的后端进行插入操作的线性表 )
Queue 接口实现类: LinkedList,PriorityQueue
常用数据结构:
Set 集合(继承 Collection 接口): 用于无序存储不可重复元素的集合(不可通过索引访问元素)
实现类: HashSet 集合, LinkedHashSet 集合, TreeSet 集合
HashSet 集合: 基于哈希表(jdk1.8 版本之前: 哈希表 = 数组 + 链表
jdk1.8 版本之后: 哈希表 = 数组 + 链表 或 哈希表 = 数组 + 红黑树(提高查找速度)
)的 Set 集合.
链表长度达到 8 个, 数组的长度达到 64 个, 则链表将转换为红黑树.
红黑树转链表位桶节点数量最小值 6.
HashSet 集合存储步骤:
1. 使用哈希算法计算元素对应的哈希值, 使用此哈希值作为地址存储 (hashCode() 方法)
2. 判断此哈希值对应的位置上是否已经存有元素
3. 若没有就将此元素存储到该位置上
4. 若有则使用 equals 方法判断两个对象是否相等, 相等就不存储, 不相等则与上个元素存在一起
重写 hashCode() 用于获得元素的存储位置
重写 equals() 用于在两个元素位置相同的时候比较两个元素是否相等
实体类重写以上两个方法可以避免添加重复对象
LinkedHashSet 集合: 基于双向链表和哈希表, 继承自 HashSet 的 Set 集合.
使用链表维护输入顺序
TreeSet 集合: 基于红黑树, 实现了 Set 接口, 具有排序功能的 Set 集合.
实体类进行 treeset 排序时需要实现 Comparable 接口
Comparable 接口: 使实现类自身具备某种比较规则以便对其对象进行 自然排序的接口.
自然排序: 是要求自定义类实现 Comparable 接口并实现其 compareTo(Object obj)方法, 在此方法中指定排序规则的算法.
- public class Student implements Comparable {
- public int compareTo(Student o) {// 重写比较方法, 返回值为整数
- return this.age - o.age;// 结果为负数, 排在 o 对象之前
- // 结果为正数, 排在 o 对象之后
- // 结果为 0, 说明两个对象相等
- // 返回年龄的差, 说明年龄小的排在前
- }
- }
- // 如果插入年龄相同的两个对象, 则按照姓名排序
- public class Student implements Comparable {
- public int compareTo(Student o) {
- if(this.age == o.age)
- return this.name.compareTo(o.name);
- return this.age - o.age;
- }
- }
Comparator 比较器: 在外部自定义比较规则以便容器对其存储数据进行 定制排序的对象.
定制排序: 是要求自定义类实现 Compartor 接口并重写其 compare(Object arg0, Object arg1)方法, 在此方法中依据 XX 属性进行排序的算法. 也称比较器排序.
使用自定义比较器时注意: 将比较器作为参数传入 TreeSet 构造器中
- // 创建比较器类 MyComparator
- public class MyComparator implements Comparator{
- public int compare(Object arg0, Object arg1) {
- Student o1=(Student)arg0;
- Student o2=(Student)arg1;
- if(o1.getAge() == o2.getAge())
- return o1.getName().compareTo(o2.getName());
- return o1.getAge() - o2.getAge();
- }
- }
- TreeSet<Student> set = new TreeSet<Student>(new MyComparator());// 将比较器作为参数传入 TreeSet 构造器中
- set.add(new Student("Joker", 18));
- set.add(new Student("Faker", 16));
- set.add(new Student("Sky", 23));
- set.add(new Student("Petter", 23));
- for (Student s : set) {
- System.out.println(s);
- }
Set 集合的使用场景:
当要求数据是不重复, 且无序的可用 HashSet 集合.
当要求数据不能重复, 且要排序并不能为空选择 TreeSet 集合
Map 集合: 容器框架中以键值对形式存储元素的容器.
实现类: HashMap ,TreeMap,Hashtable
HashMap 集合: 基于哈希表实现, 线程不安全的 Map 容器
实现类: LinkedHashMap
HashSet 底层是 HashMap 实现的.
HashMap 遍历输出的方法:
keySet() 获取所有键的集合
values() 获取所有值得集合
entry() 遍历输出键值对
注意: hashMap 集合添加 key = 自定义对象元素时, 该对象需重写 hashCode()和 equals()方法
hashMap:key 可以为 null, 且 key 唯一, value 可以为 null, 且多个 value 可以重复, 线程不安全
LinkedHashMap 集合: 是继承自 HashMap, 基于双向链表存取有序 的 Map 容器.(哈希表 + 双向链表)
特点: LinkedkedHashSet 底层就是 LinkedHashMap 实现的
LinkedHashMap 是 HashMap 的子类; 只是比 HashMap 多了一条链, 用于保存添加元素的顺序.
key 唯一, value 不唯一 ,key value 都可为空 线程不安全, 输出顺序与添加顺序一致.
Hashtable 集合: 是基于基于哈希表实现的, 线程安全的 Map 容器.
特点: key 唯一, value 不唯一 key value 都不可为空 线程安全
TreeMap 集合: 是基于红黑树实现的, 具有排序功能的 Map 容器.(根据其键进行自然排序的功能, 根据创建对象时提供的 Comparator 进行排序)
特点 :TreeSet 底层就是 TreeMap 实现的
key 唯一, value 不唯一 针对键排序 线程非安全 key 不可以为 null
注意: 遍历时需定制比较规则 (1. 创建比较器类实现 Comparator 2.TreeMap<Person,String> t = new TreeMap<Person,String>(new MyComparator()) ;)
Map 集合的使用场合:
当需要存储键值对, 都是无序的首选 HashMap .
当需要存储键值对并按 key 排序可以选择 TreeMap.
当需要存储键值对并保持插入顺序选择 LinkedHashMap .
需要线程同步, 首选 Hashtable.
三, 迭代器(Iterator)
常用方法:
使用演示:
调用 Iterator()得到一个指向集合序列第一个元素的迭代器;
用循环调用 hasNext()方法, 如果有元素, 返回 true;
在循环中, 使用 next()方法获得集合的下一个元素;
- ArrayList dogs = new ArrayList<Dog>();
- Iterator<Dog> it=dogs.iterator();
- while(it.hasNext()){
- System.out.println(it.next());
- }
ListIterator 迭代器(列表迭代器):
在 iterator 的基础上新增的一种迭代器, 它新增了 hasprevious()和 previous()方法, 可以进行向前遍历. 具有双向遍历列表的功能.
- ArrayList dogs = new ArrayList<Dog>();
- .....
- dogs.add(ououDog);
- dogs.add(yayaDog);
- dogs.add(meimeiDog);
- dogs.add(feifeiDog);
- ListIterator<Dog> iter = dogs.listIterator() ;
- System.out.println("由前向后输出:") ;
while(iter.hasNext()){ 判断是否有下一个元素
Dog dog = iter.next() ; 遍历下一个元素
- System.out.print("\t"+dog + "\n") ;
- }
- System.out.println("\n 由后向前输出:") ;
while(iter.hasPrevious()){ 判断是否有前一个元素
Dog dog = iter.previous() ; 遍历前一个元素
- System.out.print("\t"+dog + "\n") ;
- }
foreach 的使用:
for(元素类型 t 元素变量 x : 遍历对象 obj){ 引用了 x 的 java 语句; }
- for(Dog dog:dogs){
- System.out.print("\t"+dog + "\n") ;
- //foreach 一般只用于遍历集合!
- }
foreach 的特点:
java5 的新特征 ,for 语句的特殊简化版本 遍历数组, 集合方便
三种集合遍历方式:
- //for 循环
- for (int i = 0; i <1000000; i++) {
- temp = list.get(i);
- syso(temp);
- }
- // 迭代器
- while(it.hasNext()){
- temp = it.next();
- syso(temp);
- }
- //foreach
- for(Object t : list)
- temp = t;
- syso(temp);
- }
效率: for 循环 > iterator 迭代器 > foreach
来源: http://www.bubuko.com/infodetail-3398281.html