一、集合的定义
集合:是在计算机中用于存储一种或多种引用类型数据,并且长度可变的容器。
外延: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构造器中
//创建比较器类 MyComparatorpublic 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
原文地址:https://www.cnblogs.com/haogege1204/p/12240235.html