目录
第八章集合
一、集合概述
-
集合:存储数据的容器
-
集合的特点:(与数组的区别)
👉数组长度不可改变,集合长度可变
👉数组的功能单一,集合提供了增删改查元素的丰富API
👉数组存储的元素特点单一(有序可重复),不同的集合存储特点不尽相同
👉数组可以存储基本数据类型和引用数据类型的元素,集合只能存储引用数据类型元素 -
集合框架体系:
二、Collection接口
👀java.util.Collection是一个顶层接口,表示的集合是一组对象。
常用API:👇
1、添加元素
(1)add(E obj):添加元素对象到当前集合中
(2)addAll(Collection<? extends E> other):添加other集合中的所有元素对象到当前集合中,即this = this ∪ other
2、删除元素
(1) boolean remove(Object obj) :从当前集合中删除第一个找到的与obj对象equals返回true的元素。
(2)boolean removeAll(Collection<?> coll):从当前集合中删除所有与coll集合中相同的元素。即this = this - this ∩ coll
(3) void clear(); 清空集合
3、判断
(1)boolean isEmpty():判断当前集合是否为空集合。
(2)boolean contains(Object obj):判断当前集合中是否存在一个与obj对象equals返回true的元素。
(3)boolean containsAll(Collection<?> c):判断c集合中的元素是否在当前集合中都存在。即c集合是否是当前集合的“子集”。
4、获取元素个数
(1)int size():获取当前集合中实际存储的元素个数
5、交集
(1)boolean retainAll(Collection<?> coll):当前集合仅保留与c集合中的元素相同的元素,即当前集合中仅保留两个集合的交集,即this = this ∩ coll;
6、转为数组
(1)Object[] toArray():返回包含当前集合中所有元素的数组
三、Iterator迭代器
👊👊👊Collection集合可以通过iterator()方法得到一个Iterator迭代器,用于遍历Collection集合。
👉Iterator是一个接口,主要包含三个方法:
boolean hasNext();//判断是否有下一个元素
Object next();//取出下一个元素
void remove();//删除当前元素
-
迭代器的基本使用
//创建Collection集合,多态形式 Collection<String> coll = new ArrayList<>(); //添加元素 coll.add("hello"); coll.add("java"); coll.add("abc"); //创建迭代器 Iterator<String> it = coll.iterator(); while(it.hasNext()){ String s = it.next(); System.out.println(s); }
-
迭代器的实现原理
-
foreach循环
🥳 JDK5的新特性,也称为增强for循环,主要用来遍历数组或Collection集合。遍历Collection集合时,底层实现还是Iterator迭代器。
👉实现了Iterable接口的类都可以使用Iterator迭代器遍历也就可以使用增强for遍历。
int[] arr = {11,22,33}; //遍历数组 for(int i : arr){//这里的i表示每个元素 System.out.println(i); } //创建Collection集合 Collection<String> c = new ArrayList<>(); c.add("abc"); c.add("cba"); //遍历集合 for(String s : c){ System.out.println(s); }
-
迭代器的快速失败机制
☹️当迭代器在遍历集合时,使用迭代器之外的方法修改集合,可能会导致最终数据不准确甚至更大的影响。迭代器不允许做出此操作,会立即抛出并发修改异常,阻止此操作。这就是迭代器的快速失败机制。
☹️快速失败机制不会得到保证。
迭代器如何实现的快速失败机制?
🌂所有Collection集合都有一个属性modCount用于记录集合的修改次数,当通过集合创建了迭代器后,会记录此时的modCount值,并且迭代器遍历集合时每次取出元素都会验证modCount值是否修改过,如果修改过表示集合被修改了,会立即抛出并发修改异常。
四、List集合
-
java.util.List接口是Collection接口的典型子接口
-
List集合的特点:👇👇👇
-
元素有序,可重复
-
都可以通过索引访问元素
-
-
List接口的特有方法(都与索引有关)
👉添加元素
-
void add(int index, E ele)
-
boolean addAll(int index, Collection<? extends E> eles)
👉获取元素
-
E get(int index)
-
List subList(int fromIndex, int toIndex)
👉获取元素索引
-
int indexOf(Object obj)
-
int lastIndexOf(Object obj)
👉删除和替换元素
-
E remove(int index)
-
E set(int index, E ele)
-
-
List集合的遍历方式👇👇👇
-
迭代器遍历
-
foreach循环遍历
-
普通for循环遍历
-
-
-
ArrayList实现类
java.util.ArrayList是List接口的典型实现类
特点:
-
👉底层结构:数组
-
👉效率:(通过索引)查询快,增删慢
-
👉线程不安全。
-
👉对比Vector类:底层结构是数组,线程安全,不推荐使用。
源码分析:
ArrayList底层实现:可变长的数组,有索引,查询效率高,增删效率低 构造方法: new ArrayList(): jdk6中,空参构造直接创建10长度的数组 jdk7(新版)jdk8中,默认初始容量0,在添加第一元素时初始化容量为10 new ArrayList(int initialCapacity): 指定初始化容量 添加元素:add(E e); 首次添加元素,初始化容量为10 每次添加修改modCount属性值 每次添加检查容量是否足够,容量不足时需要扩容,扩容大小为原容量的1.5倍 移除元素:remove(E e); 每次成功移除元素,修改modCount值 每次成功移除需要需要移动元素,以保证所以元素是连续存储的(删除操作效率低的原因)
-
-
LinkedList实现类
-
LinkedList集合特点
👉底层结构:双向链表
👉效率:增删快,查询慢(首尾元素操作效率高)
-
特有方法:(首、尾元素的操作,效率高):
-
void addFirst(Object obj )
-
void addLast(Object obj )
-
Object getFirst()
-
Object getLast()
-
Object removeFirst()
-
Object removeLast ()
-
-
队列与栈结构
-
ListIterator
🧐List 集合额外提供了一个 listIterator() 方法,该方法返回一个 ListIterator 对象, ListIterator 接口继承了 Iterator 接口,提供了专门操作 List 的方法:
-
void add():通过迭代器添加元素到对应集合
-
void set(Object obj):通过迭代器替换正迭代的元素
-
void remove():通过迭代器删除刚迭代的元素
-
boolean hasPrevious():如果以逆向遍历列表,往前是否还有元素。
-
Object previous():返回列表中的前一个元素。
-
int previousIndex():返回列表中的前一个元素的索引
-
boolean hasNext()
-
Object next()
-
int nextIndex()
-
-
五、Set集合
-
java.util.Set接口是Collection的典型子接口
👉特点:元素唯一
-
HashSet实现类
👉特点:元素唯一,无序
👉底层结构:哈希表
👉效率:综合较高
👉去重原理:(判断元素重复的依据)
👉先比较元素的hashCode值,再进行equals比较,都相同则认为是相同元素。
-
LinkedHashSet实现类
👉是HashSet的子类,
👉特点:元素唯一,有序
👉底层结构:哈希表基础上又维护一个链表,用于保证元素的迭代顺序。
👉效率:略低于HashSet
-
TreeSet实现类
👉特点:元素唯一,无序,实现了排序
👉底层结构:红黑树-一种相对平衡的二叉树
👉效率:查询效率高于链表
👉存取元素过程:
-
存储过程:大的放右边,小的放左边
-
遍历过程:中序遍历,即左-中-右
TreeSet集合的元素必须可以比较大小,那么要求:
-
元素的类型必须实现Comparable接口
-
创建TreeSet集合时传入Comparator比较器,用于比较元素大小。
-
六、Map集合
java.util.Map是一个接口,表示一组键值对。
-
Map的特点:
👉元素唯一,通过key可以获取value
-
Map集合的常用方法:
添加操作
-
👉V put(K key,V value)
-
👉void putAll(Map<? extends K,? extends V> m)
删除
-
👉void clear()
-
👉V remove(Object key)
元素查询的操作
-
👉V get(Object key)
-
👉boolean containsKey(Object key)
-
👉boolean containsValue(Object value)
-
👉boolean isEmpty()
元视图操作的方法:
-
👉Set<K> keySet()
-
👉Collection<V> values()
-
👉Set<Map.Entry<K,V>> entrySet()
其他方法
-
👉int size()
-
-
Map集合的遍历:
//创建Map集合 Map<String,Integer> map = new HashMap<>(); //添加元素 map.put("tom",18); map.put("jack",20); map.put("rose",19); map.put("jerry",18); //遍历方式一: Set<String> set = map.keySet(); for(String key : set){ Integer value = map.get(key); System.out.println(key+"="+value); } //遍历方式二: Set<Map.Entry<String,Integer>> set = map.entrySet(); for(Map.Entry<String,Integer> entry: set){ String key = entry.getKey(); Integer value = entry.getValue(); System.out.println(key+"="+value); }
-
HashMap实现类
Map接口的典型实现类
-
👉特点:元素唯一,无序,key和value可以使用null
-
👉底层结构:哈希表=数组+链表+红黑树(JDK8)
-
👉效率:综合效率高
-
👉判断元素重复的依据:
先比较元素key 的hashCode值,再进行equals比较,如果都相同则认为是相同元素
-
👉比较Hashtable实现类:Hashtable是线程安全的,不能使用null作为key和value
-
-
LinkedHashMap实现类
是HashMap的子类
-
👉特点:元素唯一,有序
-
👉底层结构:哈希表基础上又维护一个链表,用于保证元素的迭代顺序
-
👉效率:略低于HashMap
-
-
TreeMap实现类
-
👉特点:元素唯一,无序,但实现了排序(大小顺序)
-
👉底层结构:红黑树-一种相对平衡的二叉树
-
👉效率:查询效率高于链表
-
-
Properties集合
是Hashtable的子类
-
👉特点:key和value都是字符串
-
👉特有方法:
-
void setProperty(String key,String value);
-
String getProperty(String key);
-
-
示例:
Properties prop = new Properties(); //添加元素 prop.setProperty("name","tom"); prop.setProperty("age","18"); //根据key获取value String name = prop.get("name");
-
七、Collections工具类
😝Collections 是一个操作 Set、List 和 Map 等集合的工具类。Collections 中提供了一系列静态的方法对集合元素进行排序、查询和修改等操作,还提供了对集合对象设置不可变、对集合对象实现同步控制等方法:
-
public static <T> boolean addAll(Collection<? super T> c,T... elements)将所有指定元素添加到指定 collection 中。
-
public static <T> int binarySearch(List<? extends Comparable<? super T>> list,T key)在List集合中查找某个元素的下标,但是List的元素必须是T或T的子类对象,而且必须是可比较大小的,即支持自然排序的。而且集合也事先必须是有序的,否则结果不确定。
-
public static <T> int binarySearch(List<? extends T> list,T key,Comparator<? super T> c)在List集合中查找某个元素的下标,但是List的元素必须是T或T的子类对象,而且集合也事先必须是按照c比较器规则进行排序过的,否则结果不确定。
-
public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll)在coll集合中找出最大的元素,集合中的对象必须是T或T的子类对象,而且支持自然排序
-
public static <T> T max(Collection<? extends T> coll,Comparator<? super T> comp)在coll集合中找出最大的元素,集合中的对象必须是T或T的子类对象,按照比较器comp找出最大者
-
public static void reverse(List<?> list)反转指定列表List中元素的顺序。
-
public static void shuffle(List<?> list) List 集合元素进行随机排序,类似洗牌
-
public static <T extends Comparable<? super T>> void sort(List<T> list)根据元素的自然顺序对指定 List 集合元素按升序排序
-
public static <T> void sort(List<T> list,Comparator<? super T> c)根据指定的 Comparator 产生的顺序对 List 集合元素进行排序
-
public static void swap(List<?> list,int i,int j)将指定 list 集合中的 i 处元素和 j 处元素进行交换
-
public static int frequency(Collection<?> c,Object o)返回指定集合中指定元素的出现次数
-
public static <T> void copy(List<? super T> dest,List<? extends T> src)将src中的内容复制到dest中
-
public static <T> boolean replaceAll(List<T> list,T oldVal,T newVal):使用新值替换 List 对象的所有旧值
-
Collections 类中提供了多个 synchronizedXxx() 方法,该方法可使将指定集合包装成线程同步的集合,从而可以解决多线程并发访问集合时的线程安全问题
-
Collections类中提供了多个unmodifiableXxx()方法,该方法返回指定 Xxx的不可修改的视图。