集合
一、 java中的集合体系介绍(java.util包下)
1. 数组的缺点和优点
数组的优点
数组一旦初始化,其长度就是确定的。
数组中的多个元素是依次紧密排列的,有序的,可重复的
(优点) 数组一旦初始化完成,其元素的类型就是确定的。不是此类型的元素,就不能添加到此数组中。
(优点)元素的类型既可以是基本数据类型,也可以是引用数据类型。
数组的缺点
数组一旦初始化,其长度就不可变了。
数组中存储数据特点的单一性。对于无序的、不可重复的场景的多个数据就无能为力了。
数组中可用的方法、属性都极少。具体的需求,都需要自己来组织相关的代码逻辑。
针对于数组中元素的删除、插入操作,性能较差。
2. java集合框架体系
java.util.Collection:存储一个一个的数据 |-----子接口:List:存储有序的、可重复的数据 ("动态"数组) |---- ArrayList(主要实现类)、LinkedList、Vector |-----子接口:Set:存储无序的、不可重复的数据(高中学习的集合) |---- HashSet(主要实现类)、LinkedHashSet、TreeSet java.util.Map:存储一对一对的数据(key-value键值对,(x1,y1)、(x2,y2) --> y=f(x),类似于高中的函数) |---- HashMap(主要实现类)、LinkedHashMap、TreeMap、Hashtable、Properties
3. 学习的程度把握
(前期学习)层次1:针对于具体特点的多个数据,知道选择相应的适合的接口的主要实现类,会实例化,会调用常用的方法。
(前期学习)层次2:区分接口中不同的实现类的区别。
(生层次学习)层次3:① 针对于常用的实现类,需要熟悉底层的源码 ② 熟悉常见的数据结构
二、Collection集合
1. 常用方法
1.添加 add(E obj):添加元素对象到当前集合中 addAll(Collection other):添加other集合中的所有元素对象到当前集合中 2. 判断 int size():获取当前集合中实际存储的元素个数 boolean isEmpty():判断当前集合是否为空集合 boolean contains(Object obj):判断当前集合中是否存在一个与obj对象equals返回true的元素 boolean containsAll(Collection coll):判断coll集合中的元素是否在当前集合中都存在。即 coll集合是否是当前集合的“子集” boolean equals(Object obj):判断当前集合与obj是否相等 3.删除 void clear():清空集合元素 boolean remove(Object obj) :从当前集合中删除第一个找到的与obj对象equals返回true的元 素。 boolean removeAll(Collection coll):从当前集合中删除所有与coll集合中相同的元素。 boolean retainAll(Collection coll):从当前集合中删除两个集合中不同的元素,使得当前集合仅 保留与coll集合中的元素相同的元素,即当前集合中仅保留两个集合的交集 4.其他 T[] toArray(T[] a):返回一个数组,该数组包含此集合中的所有元素;返回的数组的运行时类型是指定 数组的类型。 Object[] toArray():返回包含当前集合中所有元素的数组 hashCode():获取集合对象的哈希值 iterator():返回迭代器对象,用于集合遍历
2. 集合与数组的相互转换
集合 —> 数组:toArray()
数组 —> 集合:调用Arrays的静态方法asList(Object … objs)
3. 向Collection中添加元素的要求
要求元素所属的类一定要重写equals()!
原因:
- 因为Collection中的相关方法(比如:contains() / remove())在使用时,要调用元素所在类的equals()。
4. 迭代器
迭代器(Iterator)的作用
用来遍历集合中的元素
如何获取迭代器(Iterator)对象
//创建集合 Collection coll = new ArrayList(); //获取迭代器 Iterator iterator = coll.iterator();
如何实现遍历
//创建集合 Collection coll = new ArrayList(); //获取迭代器 Iterator iterator = coll.iterator(); //遍历 //iterator.hasNext() 该方法是判断是否还有下个元素,有则返回true,没有则返回false while(iterator.hasNext()){ System.out.println(iterator.next()); //next():①指针下移 ② 将下移以后集合位置上的元素返回 }
增强for循环(foreach循环)的使用(jdk5.0新特性)
作用
用来遍历数组、集合
格式
//创建集合 Collection coll = new ArrayList(); //遍历 for(Object obj : coll){ System.out.println(obj); } //解释 for(要遍历的集合或数组元素的类型 临时变量 : 要遍历的集合或数组变量){ // 操作临时变量的输出 }
说明
针对于集合来讲,增强for循环的底层仍然使用的是迭代器。
增强for循环的执行过程中,是将集合或数组中的元素依次赋值给临时变量,注意:循环体中对时变量的修改,可能不会导致原有集合或数组中元素的修改
三、List接口与实现类的使用
1. List接口中存储数据的特点:
- 用于存储有序的、可以重复的数据。—> 使用List替代数组,“动态"数组
2. List中常用的方法
Collection中的15个方法
1.添加 add(E obj):添加元素对象到当前集合中 addAll(Collection other):添加other集合中的所有元素对象到当前集合中
判断
int size():获取当前集合中实际存储的元素个数
boolean isEmpty():判断当前集合是否为空集合
boolean contains(Object obj):判断当前集合中是否存在一个与obj对象equals返回true的元 素
boolean containsAll(Collection coll):判断coll集合中的元素是否在当前集合中都存在。即 coll集合是否是当前集合的“子集”
boolean equals(Object obj):判断当前集合与obj是否相等
3.删除
void clear():清空集合元素
boolean remove(Object obj) :从当前集合中删除第一个找到的与obj对象equals返回true的元 素。
boolean removeAll(Collection coll):从当前集合中删除所有与coll集合中相同的元素。
boolean retainAll(Collection coll):从当前集合中删除两个集合中不同的元素,使得当前集 合仅保留与coll集合中的元素相同的元素,即当前集合 中仅保留两个集合的交集
4.其他
T[] toArray(T[] a):返回一个数组,该数组包含此集合中的所有元素;返回的数组的运行时类型是 指定数组的类型。
Object[] toArray():返回包含当前集合中所有元素的数组
hashCode():获取集合对象的哈希值
iterator():返回迭代器对象,用于集合遍历因为List是有序的,进而就有索引,进而就会增加一些针对索引操作的方法。
1.插入元素 void add(int index, Object ele):在index位置插入ele元素 boolean addAll(int index, Collection eles):从index位置开始将eles中的所有元素添加进来 2.获取元素 Object get(int index):获取指定index位置的元素 List subList(int fromIndex, int toIndex):返回从fromIndex到toIndex位置的子集合 3.获取元素索引 int indexOf(Object obj):返回obj在集合中首次出现的位置 int lastIndexOf(Object obj):返回obj在当前集合中末次出现的位置 4.删除和替换元素 Object remove(int index):移除指定index位置的元素,并返回此元素 Object set(int index, Object ele):设置指定index位置的元素为ele
小结
1.增 add(Object obj) addAll(Collection coll) 2.删 remove(Object obj) remove(int index) 3.改 set(int index, Object ele) 4.查 get(int index) 5.插 add(int index, Object ele) addAll(int index, Collection eles) 6.长度 size() 7.遍历 iterator() :使用迭代器进行遍历 增强for循环 一般的for循环:因为List是有序的因而可以使用一般循环进行遍历
3. List及其实现类特点
java.util.Collection:存储一个一个的数据 |-----子接口:List:存储有序的、可重复的数据 ("动态"数组) |---- ArrayList(jdk1.2):List的主要实现类;线程不安全的、效率高;底层使用 Object[]数组存储在添加数据、查找数据时,效率较高;在插 入、删除数据时,效率较低(频繁添加时使用) |---- LinkedList(jdk1.2):底层使用双向链表的方式进行存储;在对集合中的数据进行频 繁的删除、入操作时,建议使用此类在插入、删除数据时,效率 较高;在添加数据、查找数据时,效率较低;(频繁删除时使 用) |---- Vector:List的古老实现类(jdk1.0);线程安全的、效率低;底层使用Object[]数组 存储
- [面试题] :ArrayList、Vector的区别? ArrayList、LinkedList的区别?
四、Set接口
1.Set接口及其实现类的特点
java.util.Collection:存储一个一个的数据 |-----子接口:Set:存储无序的、不可重复的数据(高中学习的集合) |---- HashSet:主要实现类;底层使用的是HashMap,即使用数组+单向链表+红黑树结构进行 存储。(jdk8中) |---- LinkedHashSet:是HashSet的子类;在现有的数组+单向链表+红黑树结构的基 础上,又添加了一组双向链表,用于记录添加元素的先后顺序。 即:我们可以按照添加元素的顺序实现遍历。便于频繁的查询操 作。 |---- TreeSet:底层使用红黑树存储。可以按照添加的元素的指定的属性的大小顺序进行遍 历。
2. 开发中的使用频率及场景
- 较List、Map来说,Set使用的频率比较少。
- 用来过滤重复数据
3. Set中常用的方法
1.添加 add(E obj):添加元素对象到当前集合中 addAll(Collection other):添加other集合中的所有元素对象到当前集合中 2. 判断 int size():获取当前集合中实际存储的元素个数 boolean isEmpty():判断当前集合是否为空集合 boolean contains(Object obj):判断当前集合中是否存在一个与obj对象equals返回true的元 素 boolean containsAll(Collection coll):判断coll集合中的元素是否在当前集合中都存在。即 coll集合是否是当前集合的“子集” boolean equals(Object obj):判断当前集合与obj是否相等 3.删除 void clear():清空集合元素 boolean remove(Object obj) :从当前集合中删除第一个找到的与obj对象equals返回true的元 素。 boolean removeAll(Collection coll):从当前集合中删除所有与coll集合中相同的元素。 boolean retainAll(Collection coll):从当前集合中删除两个集合中不同的元素,使得当前集 合仅保留与coll集合中的元素相同的元素,即当前集合 中仅保留两个集合的交集 4.其他 T[] toArray(T[] a):返回一个数组,该数组包含此集合中的所有元素;返回的数组的运行时类型是 指定数组的类型。 Object[] toArray():返回包含当前集合中所有元素的数组 hashCode():获取集合对象的哈希值 iterator():返回迭代器对象,用于集合遍历
4. Set中无序性、不可重复性的理解(以HashSet及其子类为例说明)
- 无序性: != 随机性。
- 添加元素的顺序和遍历元素的顺序不一致,这样并不是无序性,无序性是与添加的元素的位置有 关,不像ArrayList一样是依次紧密排列的。 这里是根据添加的元素的哈希值,计算的其在数组中的存储位置。此位置不是依次排列的,表现为无序性。
- 不可重复性:添加到Set中的元素是不能相同的。
- 比较的标准,需要判断hashCode()得到的哈希值以及equals()得到的boolean型的结果。
哈希值相同且equals()返回true,则认为元素是相同的。如果hashCode()不一样则不会继续去判断equals()
5. 添加到HashSet/LinkedHashSet中元素的要求
- 要求元素所在的类要重写两个方法:equals() 和 hashCode()。
- 同时,要求equals() 和 hashCode()要保持一致性!我们只需要在编译器中自动生成两个方法的重写即可,即能保证两个方法的一致性。
6. TreeSet的使用
- 底层的数据结构:
- 红黑树
- 添加数据后的特点:
- 可以按照添加的元素的指定的属性的大小顺序进行遍历。
- 向TreeSet中添加的元素的要求:
- 要求添加到TreeSet中的元素必须是同一个类型的对象,否则会报ClassCastException.
- 添加的元素需要考虑排序:① 自然排序 ② 定制排序
- 判断数据是否相同的标准
- 不再是考虑hashCode()和equals()方法了,也就意味着添加到TreeSet中的元素所在的类不需要重写hashCode()和equals()方法了
- 比较元素大小的或比较元素是否相等的标准就是考虑自然排序或定制排序中,compareTo()或compare()的返回值。
- 如果compareTo()或compare()的返回值为0,则认为两个对象是相等的。由于TreeSet中不能存放相同的元素,则后一个相等的元素就不能添加到TreeSet中。
五、Map接口
1. Map及其实现类对比
java.util.Map:存储一对一对的数据(key-value键值对,(x1,y1)、(x2,y2) --> y=f(x),类似于高中的 函数) |---- HashMap:主要实现类;线程不安全的,效率高;可以添加null的key和value值;底层使用数组+单向链 表+红黑树结构存储(jdk8) |---- LinkedHashMap:是HashMap的子类;在HashMap使用的数据结构的基础上,增加了一对双向链 表,用于记录添加的元素的先后顺序,进而我们在遍历元素时,就可以按照添加的 顺序显示。开发中,对于频繁的遍历操作,建议使用此类。 |---- TreeMap:底层使用红黑树存储;可以按照添加的key-value中的key元素的指定的属性的大小顺序进行 遍历。需要考虑使用①自然排序 ②定制排序。 |---- Hashtable:古老实现类;线程安全的,效率低;不可以添加null的key或value值;底层使用数组+单向 链表结构存储(jdk8) |---- Properties:其key和value都是String类型。常用来处理属性文件。 [面试题] 区别HashMap和Hashtable、区别HashMap和LinkedHashMap、HashMap的底层实现(① new HashMap() ② put(key,value))
2.HashMap中元素的特点
- HashMap中的所有的key彼此之间是不可重复的、无序的。所有的key就构成一个Set集合。—>key所在的类要重写hashCode()和equals()
- HashMap中的所有的value彼此之间是可重复的、无序的。所有的value就构成一个Collection集合。—>value所在的类要重写equals()
- HashMap中的一个key-value,就构成了一个entry。
- HashMap中的所有的entry彼此之间是不可重复的、无序的。所有的entry就构成了一个Set集合。
3.Map中的常用方法
1. 添加、修改操作: Object put(Object key,Object value):将指定key-value添加到(或修改)当前map对象中 void putAll(Map m):将m中的所有key-value对存放到当前map中 2.删除操作: Object remove(Object key):移除指定key的key-value对,并返回value void clear():清空当前map中的所有数据 3.元素查询的操作: Object get(Object key):获取指定key对应的value boolean containsKey(Object key):是否包含指定的key boolean containsValue(Object value):是否包含指定的value int size():返回map中key-value对的个数 boolean isEmpty():判断当前map是否为空 boolean equals(Object obj):判断当前map和参数对象obj是否相等 4.元视图操作的方法: Set keySet():返回所有key构成的Set集合 Collection values():返回所有value构成的Collection集合 Set entrySet():返回所有key-value对构成的Set集合
4.小结:
1.增: put(Object key,Object value) putAll(Map m) 2.删: Object remove(Object key) 3.改: put(Object key,Object value) putAll(Map m) 4.查: Object get(Object key) 5.长度: size() 6.遍历: 遍历key集:Set keySet() 遍历value集:Collection values() 遍历entry集:Set entrySet()
5.TreeMap的使用
- 底层使用红黑树存储;
- 可以按照添加的key-value中的key元素的指定的属性的大小顺序进行遍历。
- 需要考虑使用①自然排序 ②定制排序。
- 要求:向TreeMap中添加的key必须是同一个类型的对象。
6.Hashtable与Properties的使用
- Properties:是Hashtable的子类,其key和value都是String类型的,常用来处理属性文件。
六、Collections工具类的使用
1.Collections概述
- Collections 是一个操作 Set、List 和 Map 等集合的工具类。
2.常用方法
排序操作: reverse(List):反转 List 中元素的顺序 shuffle(List):对 List 集合元素进行随机排序 sort(List):根据元素的自然顺序对指定 List 集合元素按升序排序 sort(List,Comparator):根据指定的 Comparator 产生的顺序对 List 集合元素进行排序 swap(List,int i, int j):将指定 list 集合中的 i 处元素和 j 处元素进行交换 查找 Object max(Collection):根据元素的自然顺序,返回给定集合中的最大元素 Object max(Collection,Comparator):根据 Comparator 指定的顺序,返回给定集合中的最大元 素 Object min(Collection):根据元素的自然顺序,返回给定集合中的最小元素 Object min(Collection,Comparator):根据 Comparator 指定的顺序,返回给定集合中的最小元 素 int binarySearch(List list,T key)在List集合中查找某个元素的下标,但是List的元素必须是T 或T的子类对象,而且必须是可比较大小的,即支持自然排序的。而且集合也事先必须 是有序的,否则结果不确定。 int binarySearch(List list,T key,Comparator c)在List集合中查找某个元素的下标,但是 List的元素必须是T或T的子类对象,而且集合也事先必须是按照c比较器规则进行排序 过的,否则结果不确定。 int frequency(Collection c,Object o):返回指定集合中指定元素的出现次数 复制、替换 void copy(List dest,List src):将src中的内容复制到dest中 boolean replaceAll(List list,Object oldVal,Object newVal):使用新值替换 List 对象 的所有旧值 提供了多个unmodifiableXxx()方法,该方法返回指定 Xxx的不可修改的视图。 添加 boolean addAll(Collection c,T... elements)将所有指定元素添加到指定 collection 中。 同步 Collections 类中提供了多个 synchronizedXxx() 方法,该方法可使将指定集合包装成线程同步的集 合,从而可以解决多线程并发访问集合时的线程安全问题
3.面试题:区分Collection 和 Collections
- Collection:集合框架中的用于存储一个一个元素的接口,又分为List和Set等子接口。
- Collections:用于操作集合框架的一个工具类。此时的集合框架包括:Set、List、Map