IDEA相关配置
- 配置代码模板
集合的理解和好处
前面我们保存多个数据使用的是数组,那么数组有不足的地方,我们分析一下。
-
数组
1)长度开始时必须指定,而且一旦指定,不能更改
2)保存的必须为同一数据类型的元素
3)使用数组进行增加/删除元素的比较麻烦:
如:
Person[] pers = new Person[1];//长度是1 per[0] = new Person(); //增加新的Person对象? Person[] pers2 = new Person[pers.length+1];//新建数组 for(){}//拷贝pers数组的元素到pers2 pers2[pers2.length-1] = new Person();//添加新的对象
-
集合
1)可以动态保存任意多个对象,使用比较方便
2)提供了一系列方便的操作对象的方法:add、remove、set、get(增删改查)等
3)使用集合添加,删除新元素的代码简洁了
集合的框架体系
Collection接口和常用方法
-
Collection接口实现类的特点
public interface Collection extends Iterable
1)Collection实现子类可以存放多个元素,每个元素可以是Object
2)有些Collection的实现类,可以存放重复的元素,有些不可以
3)有些Collection的实现类,是有序的,有些是无序的
4)Collection接口没有直接的实现子类,是通过它的子接口Set和List来实现的
-
Collection接口常用方法,以实现子类ArrayList来演示,CollectionMethod.java
1)add:添加单个元素
2)remove:删除指定元素
3)contains:查看元素是否存在
4)size:获取元素的个数
5)isEmpty:判断是否为空
6)clear:清空
7)addAll:添加多个元素
8)containsAll:查看多个元素是否都存在
9)removaAll:删除多个元素
10)说明:以ArrayList实现类来演示
Collection col = new ArrayList(); col.add("小龙女"); col.add(100); col.add(true); col.add("小龙女"); col.add(new Integer(10)); col.remove("小龙女"); boolean contains = col.contains(10); System.out.println(col.size()); System.out.println(col.isEmpty()); col.clear(); Collection c = new ArrayList(); c.add("AA"); c.add("BB"); c.add("CC"); col.addAll(c); Collection c2 = new ArrayList(); c2.add("CC"); c2.add("AA"); boolean containsAll = col.containsAll(c2); col.removeAll(c2);
-
Collection接口遍历元素方式1-使用Iterator(迭代器)
-
基本介绍
1)Iterator对象称为迭代器,主要用于遍历Collection集合中的元素
2)所有实现了Collection接口的集合类都有一个Iterator()方法,用以返回一个实现了Iterator接口的对象,即可以返回一个迭代器
3)Iterator的结构
4)Iterator仅用于遍历集合,Iterator本身并不存放对象
-
迭代器的执行原理
Iterator iterator = coll.iterator();//得到一个集合的迭代器 //hasNext():判断是否还有下一个元素 while(iterator.hasNext()){ //next():1.下移,2.将下移以后集合位置上的元素返回 System.out.println(iterator.next()); }
-
-
Collection接口遍历对象方式2–for循环增强
增强for循环,可以代替iterator迭代器,特点:增强for就是简化版的iterator,本质一样,只能用于遍历集合或数组
-
基本语法
for(元素类型 元素名:集合名或数组名){ 访问元素 }
-
案例演示(看老师演示遍历Book,并使用Debug源码来证明)
CollectionFor.java
for(Object obj:col){ ..... }
-
List接口的常用方法
-
List接口基本介绍
List接口是Collection接口的子接口
1)List集合类中元素有序(即添加顺序和取出顺序一致)、且可重复
2)List集合中的每一个元素都有其对应的顺序索引,即支持索引(索引从0开 始)
3)List容器中的元素都对应一个整数型的徐哈好记载其在容器中的位置,可以根据序号存取容器中的元素
4)JDK API中List接口的实现类有:
常用的有:ArrayList,LinkedList和Vector
-
List接口的常用方法
List集合里添加了一些根据索引来操作集合元素的方法
1)void add(int index,Object ele);在index位置插入ele元素
2)boolean addAll(int index,Collection eles);从index位置开始将eles中的所有元素添加进来
3)Object get(int index);获取指定index位置的元素
4)int indexOf(Object obj);返回obj在集合中首次出现的位置
5)int lastIndexOf(Object obj);返回obj在集合中最后一次出现的位置
6)Object remove(int index);移除指定index位置的元素,并返回此元素
7)Object set(int index,Object obj);设置指定位置的元素为ele,相当于是替换
8)List subList(int fromIndex,int toIndex);返回从fromIndex到toIndex位置的子集合
-
List的三种遍历方式【ArrayList、LinkedList、Vector】
1)方式一:使用iterator(快捷键 itit )
Iterator iterator = col.iterator(); while(iterator.hasNext()){ Object obj = iterator.next(); }
2)方式二:使用增强for(快捷键 I(大写) )
for(Object obj : col){ ... }
3)方式三:使用普通for(快捷键 fori)
for(int i=0;i<col.size();i++){ Object obj = col.get(i); }
说明:使用LinkedList、完成 使用方式和ArrayList一样
ArrayList底层结构和源码分析
-
ArrayList的注意事项
ArrayListDetail.java
1)permits all elements,including null,Arraylist 可以加入null,并且多个
2)ArrayList 是由数组来实现数据存储的
3)ArrayList基本等同于Vector,除了ArrayList是线程不安全(执行效率高),在多线程情况下,不建议使用ArrayList
-
ArrayList的底层操作机制源码分析(重点,难点)
1)ArrayList中维护了一个Object类型的数组elementData
transient Object[] elementData;//transient 表示瞬间,短暂的,表示该属性不会被序列化
2)当创建ArrayList对象时,如果使用的是无参构造器,则初始elementData容量为0,第一次添加,则扩容elementData为10,如需要再次扩容,则扩容elementData为1.5倍
3)如果使用的是指定大小的构造器,则初始elementData容量为指定大小,如果需要扩容,则直接扩容elementData为1.5倍
//注意,注意,注意,Idea 默认情况下,Debug 显示的数据是简化后的,如果希望看到完整的 //需要做设置
Vector底层结构和ArrayList的比较
-
Vector的基本介绍
1)Vector类的定义说明
public class Vector<E> extends AbstractList<E> implements List<E>,RandomAccess,Cloneable,Serializable
2)Vector底层也是一个对象数组,protected Object[] elementData;
3)Vector是线程同步的,即线程安全,Vector类的操作方法带有synchronized
public synchronized E get(int index){ if(index >= elementCount){ throw new ArrayOutOfBoundsException(index); } return elementData[index]; }
4)在开发中,需要线程同步安全时,考虑使用Vector
LinkedList底层结构
-
LinkedList的全面说明
1)LinkedList底层实现了双向链表和双端队列特点
2)可以添加任意元素(元素可以重复),包括null
3)线程不安全,没有实现同步
-
LinkedList的底层操作机制
1)LinkedList底层维护了一个双向链表
2)LinkedList中维护了两个属性first和last分别指向 首节点和尾节点
3)每一个节点(Node对象),里面又维护prev、next、item三个属性,其中通过prev指向前一个,通过next指向后一个节点,最终实现双向链表
4)所以LinkedList的元素的添加和删除,不是通过数组来完成的,相对来说效率较高
ArrayList 和 LinkedList 比较
Set接口和常用方法
-
Set接口基本介绍
1)无序(添加和取出的顺序不一致),没有索引
2)不允许重复元素,所以最多包含一个null
3)JDK API中Set接口的实现类有:
-
Set接口的常用方法
和List接口一样,Set接口也是Collection的子接口,因此,常用方法和Collection接口一样
-
Set接口的遍历方法
同Collection的遍历方式一样,因为Set接口是Collection接口的子接口
- 可以使用迭代器
- 增强for
- 不能使用索引的方式来获取
Set接口实现类-HashSet
-
HashSet的全面说明
1)HashSet实现了Set接口
2)HashSet实际上是HashMap,看下源码
3)底层维护了一个 数组 + 链表 + 红黑树
public HashSet(){ map = new HashMap<>(); }
3)可以存放null值,但是只能存放一个
4)HashSet不保证元素是有序的,取决于hash后,再确定索引的结果(即,不保证取出的顺序与存放的顺序一致)
5)不能存放重复元素/对象,在前面Set 接口使用已经讲过
-
HashSet底层机制说明
源码先放着,后面再看
Set接口实现类-LinkedHashSet
-
LinkedHashSet的全面说明
1)LinkedHashSet是HashSet的子类
2)LinkedHashSet底层是一个LinkedHashMap,底层维护了一个 数组 + 双向链表
3)LinkedHashSet 根据元素的hashCode值来决定元素的存储位置,同时使用链表维护元素的次序,这使得元素看起来是以插入顺序保存的
4)LinkedHashSet不允许添加重复元素
Map接口和常用方法
-
Map接口常用方法
1)put:添加
2)remove:根据key删除映射关系
3)get:根据key获取值
4)size:获取元素的个数
5)isEmpty:判断个数是否为0
6)clear:清除
7)containsKey:查找key是否存在
-
Map接口的遍历方式
1)containsKey:查找key是否存在
2)keySet:获取所有的key
3)entrySet:获取所有关系key-value
4)values:获取所有的值
-
HashMap小结
1)Map接口的常用实现类:HashMap、Hashtable、Properties
2)HashMap是Map接口适用于频率最高的实现类
3)HashMap是以kay-value对方式来存储数据(HashMap$Node类型)
4)key不能重复,但是value可以重复,允许使用null键和nul值
5)如果添加相同的key,则会覆盖原来的key-value,等同于修改(key不会替换,val会替换)
6)与HashSet一样,不保证映射的顺序,因为底层是以hash表的方式来存储的
7)HashMap没有实现同步,因此是线程不安全的
Map接口实现类-HashTable
-
HashTable的基本介绍
1)存放的元素时k-v对
2)hashtable的key和value都不能为null,否则会抛出NullPointerexception异常
3)hashtable使用方法基本和hashmap一致
4)hashtable是线程安全的(synchronize),hashmap不是
-
HashTable扩容机制
-
HashTable和HashMap对比
Map接口实现类-Properties
-
基本介绍
1)Properties类继承自HashTable类并实现了Map接口,也是使用一种k-v对的形式来保存数据
2)他的使用特点和HashMap类似
3)Properties还可以用于从 xxx.Properties 文件中,加载数据到Properties类对象,并进行读取和修改
4)说明:工作后 xxx.Properties 文件通常作为配置文件,这个知识点在IO流举例,有兴趣可以先看文章
总结-开发中如何选择集合实现类(记住)
在开发中,选择什么集合实现类,主要取决于业务操作特点,然后根据集合实现类特性进行选择,分析如下:
1)先判断存储的类型(一组对象【单列】或一组键值对【双列】)
2)一组对象【单列】:Collection接口
允许重复:List
增删多:LinkedList【底层维护了一个双向链表】
改查多:ArrayList【底层维护了 Object类型的可变数组】
不允许重复:Set
无序:HashSet【底层是HashMap,维护了一个哈希表,即(数组+链表+红黑树)】
排序:TreeSet
插入和取出顺序一致:LinkedHashSet,维护数组+双向链表
3)一组键值对【双列】:Map
键无序:HashMap【底层是:哈希表 jdk7:数组+链表,jdk8:数组+链表+红黑树】
键排序:TreeMap
键插入和取出顺序一致:LinkedHashMap
读取文件:Properties
TreeSet:略
Collections工具类
- Collections工具类介绍
1)Collections 是一个操作 Set、List 和 Map等集合的工具类
2)Collections 中提供了一系列静态的方法对集合元素进行排序、查询和修改等操作
- 排序操作:(均为static方法)
1)reverse(List):反转 List 中元素的顺序
2)shuffle(List):对 LIst 集合元素进行随机排序
3)sort(List):根据元素的自然顺序对指定 List 集合元素按升序排序
4)sort(List,Comparator):根据指定的Comparator 产生的顺序对 LIst 集合元素进行排序
5)swap(List,int,int):将指定 list 集合中的 i 处元素和 j 处元素进行交换
-
查找、替换
1)Object max(Collection):根据元素的自然顺序,返回给定集合中的最大元素
2)Object max(Collection,Comparator):根据Comparator 指定的顺序,返回给定集合中的最大元素
3)Object min(Collection)
4)Object min(Collection,Comparator)
5)int frequency(Collection,Object):返回指定集合中指定元素的出现次数
6)void copy(List dest,List src):将src中的内容复制到dest中
7)boolean replaceAll(List list,Object oldVal,Object newVal):使用新值替换 List 对象的所有旧值
HomeWork
-
查找、替换
1)Object max(Collection):根据元素的自然顺序,返回给定集合中的最大元素
2)Object max(Collection,Comparator):根据Comparator 指定的顺序,返回给定集合中的最大元素
3)Object min(Collection)
4)Object min(Collection,Comparator)
5)int frequency(Collection,Object):返回指定集合中指定元素的出现次数
6)void copy(List dest,List src):将src中的内容复制到dest中
7)boolean replaceAll(List list,Object oldVal,Object newVal):使用新值替换 List 对象的所有旧值