- 概念: 对象的容器,定义了对多个对象进行操作的常用方法,可以实现数组的功能。
- 和数组的区别:
- (1)数组长度固定,集合长度不固定。
- (2)数组可以存储基本数据类型和引用类型,集合只能存储引用类型。
- (3)装箱操作可以将基本类型装箱成引用类型,再集合保存。
- 集合都在:java.util.*; 包中
-
特点: Collection 层次结构 中的根接口。Collection 表示一组对象,这些对象也称为 collection 的元素。一些 collection 允许有重复的元素,而另一些则不允许。一些 collection 是有序的,而另一些则是无序的。JDK 不提供此接口的任何直接 实现:它提供更具体的子接口(如 Set 和 List)实现。此接口通常用来传递 collection,并在需要最大普遍性的地方操作这些 collection。
-
常用方法:
-
boolean add(Object obj) // 添加一个对象
-
boolean addAll(Collection c) // 将一个集合中的所有对象添加到此集合中
-
void clear() // 清空此集合中的所有对象
-
boolean contains(Object o) // 检查此集合中是否包含o对象
-
boolean equals(Object o) // 比较此集合是否与指定对象相等
-
boolean isEmpty(Object o) // 判断此集合是否为空
-
boolean remove(Object o) // 在此集合中移出o对象
-
int size() // 返回此集合中的元素个数
-
Object[] toArray() // 将此集合转换为数组
-
package com.stu.szh.kuangjia;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class CollectionTest {
public static void main(String[] args) {
// 创建集合
Collection collection = new ArrayList<>();
// 添加元素
collection.add("苹果");
collection.add("香蕉");
collection.add("荔枝");
collection.add("葡萄");
collection.add("西瓜");
System.out.println("删除前集合元素的个数为: "+collection.size());
// 删除元素
// collection.remove("葡萄");
System.out.println("删除后集合元素的个数为: "+collection.size());
// 删除全部元素
// collection.clear();
System.out.println("清空后集合元素的个数为: "+collection.size());
// 遍历元素,
// 方法一:增强for循环
for (Object object: collection) {
System.out.println("集合中的元素为:"+object);
}
System.out.println("使用迭代器遍历----------------------------------------------");
// 使用迭代器遍历集合,迭代器是专门用来遍历集合的方式
Iterator iterator = collection.iterator();
// hasNext()判断是否还有下一个元素
while (iterator.hasNext()){
// 返回迭代的下一个元素
String s = iterator.next();
System.out.println("集合中的元素为: "+s);
// 注意不能用以下方式在interator中删除元素
// 会报并发修改的错误
// collection.remove(s);
// 删除元素
iterator.remove();
}
System.out.println("集合中的元素个数为:"+collection.size());
// 判断是否有西瓜
System.out.println("集合中有西瓜吗?"+collection.contains("西瓜"));
}
}
二.List子接口
-
特点: 有序,有下标,元素可以重复。
-
方法:
- void add(int index, Object o) // 在index位置插入对象o
- boolean addAll(int index, Collection c) // 将一个集合中的元素添加到此集合中的index位置
- Object get(int index) // 返回集合中指定位置的元素
- List subList(int fromIndex, int toIndex) // 返回fromIndex和toIndex之间的集合元素 (含头不含尾)
-
List接口的使用
package com.stu.szh.kuangjia;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
public class ListDemo {
public static void main(String[] args) {
// 创建集合
List
2.1 List实现类ArrayList
-
数组结构,必须开辟连续空间,查询块,增删慢
-
JDK1.2加入,运行效率快,线程不安全
-
源码分析
-
private static final int DEFAULT_CAPACITY = 10; // 默认容量
-
注意:如果没有向集合中添加任何元素时,容量为0;当添加任意一个元素后,容量为10.
-
transient Object[] elementData; // 存放元素的数组
-
private int size; // 实际元素个数
-
boolean add(E e) // 添加元素 public boolean add(E e) { ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; return true; } private static int calculateCapacity(Object[] elementData, int minCapacity) { if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { return Math.max(DEFAULT_CAPACITY, minCapacity); } return minCapacity; } private void ensureCapacityInternal(int minCapacity) { ensureExplicitCapacity(calculateCapacity(elementData, minCapacity)); } private void ensureExplicitCapacity(int minCapacity) { modCount++; // overflow-conscious code if (minCapacity - elementData.length > 0) grow(minCapacity); } private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length; int newCapacity = oldCapacity + (oldCapacity >> 1); if (newCapacity - minCapacity < 0) newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); // minCapacity is usually close to size, so this is a win: elementData = Arrays.copyOf(elementData, newCapacity); } -
扩容:当数组填满10个容量之后(满十之后右移动一位即10除以2,在在原来的容量上加上5),每次扩容1.5倍。
-
- 数组结构实现,查询快,增删慢
- JDK1.0版本,运行效率慢,线程安全
-
链表结构实现(双向链表),无需开辟连续空间,增删块,查询慢
-
源码分析
void linkLast(E e) { final Nodel = last; final Node newNode = new Node<>(l, e, null); last = newNode; if (l == null) first = newNode; else l.next = newNode; size++; modCount++; } private static class Node { E item; Node next; Node prev; Node(Node prev, E element, Node next) { this.item = element; this.next = next; this.prev = prev; } }
- 特点: 无序,无下标,元素不可重复。
- 方法: 全部继承自Collection中的方法。
-
基于HashCode实现元素不重复。
-
存储结构:哈希表(数组+链表+红黑树(jdk1.8加入))。
-
当存入元素的哈希码相同时,会调用equals进行确认,如果为true,则拒绝后者存入。
-
代码练习
package com.stu.szh.kuangjia; import java.util.HashSet; import java.util.Iterator; public class HashSetDemo { public static void main(String[] args) { HashSethashSet = new HashSet<>(); hashSet.add("刘德华"); hashSet.add("梁朝伟"); hashSet.add("郭富城"); hashSet.add("刘德华"); hashSet.add("周润发"); System.out.println("元素个数为:"+hashSet.size()); System.out.println(hashSet.toString()); System.out.println("---------------------------------------------"); hashSet.remove("郭富城"); System.out.println("元素个数为:"+hashSet.size()); System.out.println(hashSet.toString()); System.out.println("---------------------------------------------"); Iterator iterator = hashSet.iterator(); while (iterator.hasNext()){ System.out.println("元素为: "+iterator.next()); } System.out.println("---------------------------------------------"); System.out.println("是否有刘德华: "+hashSet.contains("刘德华")); System.out.println("是否为空: "+hashSet.isEmpty()); } } -
存储过程:
1. 根据hashCode计算保存的位置,如果此位置为空,则直接保存,如果不为空则执行第二步。
2. 在执行equals方法,如果equals方法为true,则认为是重复,否则,形成链表。
- 用法和HashSet基本一致,但linkedHashSet是有序的。
-
基于排列顺序实现元素不重复。
-
存储结构为红黑树(一种二叉树,小于根节点的在左边,大于根节点的再右边)。
-
实现了SortedSet接口,对集合元素自动排序(并不是按存入顺序排的,它有其自己内部的排序规则)。
-
元素对象的类型必须实现Comparable接口,重写CompareTo方法,指定排序规则。
-
通过CompareTo方法来确定是否为重复元素。
-
可以直接使用Comparator实现定制比较(比较器),使用内部类的方式实现Comparator接口。
TreeSet
persons = new TreeSet<>(new Comparator (){ @Override public int compare (Person o1, Person o2){ return 0; } });
-
方法:
- V put(K key, V value) // 将对象存入到集合中,关联键值,key重复则覆盖原值
- Object get(Object key) // 根据键获取相应的值
- keySet // 返回所有的key
- Collection values() // 返回包含所有值的Collection集合
- Set
> // 键值匹配的Set集合entrySet()
-
基本使用
package com.stu.szh.kuangjia; import java.util.HashMap; import java.util.Map; import java.util.Set; public class MapDemo { public static void main(String[] args) { Mapmap = new HashMap<>(); map.put("CN","中国"); map.put("UK","英国"); map.put("USA","美国"); map.put("CN","中国"); System.out.println("当前集合中元素个数为: "+map.size()); System.out.println("显示当前集合: "+map.toString()); System.out.println("--------------------------------------------"); // 遍历 // 第一种方法,keySet() Set keySet = map.keySet(); for(String key : keySet){ System.out.println(key+":"+map.get(key)); } System.out.println("---------------------------------------------"); // 第二种遍历entrySet(),效率高于keySet() Set > entrySet = map.entrySet(); for (Map.Entry entry : entrySet){ System.out.println(entry+":"+map.get(entry)); } System.out.println("--------------------------------------------------"); // 判断 System.out.println("是否有中国的key: "+map.containsKey("CN")); System.out.println("是否有泰国: "+ map.containsValue("泰国")); } }
-
特点:
- 基于哈希表的 Map 接口的实现。此实现提供所有可选的映射操作,并允许使用 null 值和 null 键。(除了非同步和允许使用 null 之外,HashMap 类与 Hashtable 大致相同。)此类不保证映射的顺序,特别是它不保证该顺序恒久不变。
- JDK1.2版本,线程不安全,运行效率快;允许使用null作为key或者是value。
-
HashMap() 构造一个具有默认初始容量 (16) 和默认加载因子 (0.75) 的空 HashMap。
-
存储结构: 哈希表( 数组+链表+红黑树)
-
默认初始容量为16,刚创建HashMap之后没有添加元素table= null,size=0
-
当元素个数大于阈值(16*0.75=12)时,会进行扩容,扩容后大小为原来的2倍,且目的是减少调整元素的个数
-
jdk1.8 当每个链表长度大于8,且数组元素个数大于等于64时,会调整为红黑树,目的是提高执行效率
-
jdk1.8 当链表长度小于6时,会调整成链表
-
jdk1.8以前,链表是头插入,jdk1.8以后,链表是尾插入
-
使用key的hashCode和equals作为重复依据
-
源码分析
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16 默认初始容量大小,左移四位2^4=16 static final int MAXIMUM_CAPACITY = 1 << 30; //最大容量2^30 static final float DEFAULT_LOAD_FACTOR = 0.75f; // 默认加载因子,假如当前容量为100,当集合中的元素大于100x0.75=75 // 时,就该扩容了 static final int TREEIFY_THRESHOLD = 8; // 链表长度大于8,且数组长度大于64时,就把链表转为树 static final int UNTREEIFY_THRESHOLD = 6; // 当树的元素个数小于6时,就转为链表 static final int MIN_TREEIFY_CAPACITY = 64; // 数组最大为64 transient Node
[] table; // 哈希表中的数组
- 特点: JDK1.0版本,线程安全,运行效率慢;不允许null作为key或者是value。
- 实现了SortedMap接口(是Map的子接口),可以对key自动排序。
- 存储结构为红黑树。
- 注意也要实现Comparable接口,CompareTo方法;或者可以使用 Comparator;
-
概念: 集合工具类,定义了除存取以外的集合常用方法。
-
方法:
-
public static void reverse(List> list) // 反转集合中元素的顺序
-
public static void shuffle(List> list) // 随机重置集合元素的顺序
-
public static void sort(List list) // 升序排序(元素类型必须实现Comparable接口)
-
// binarySearch二分查找(要求集合事先必须是有序的),找出所需元素。
Integer[] arr = list.toArray(new[0] Interger); // 将集合list转换成数组arr
-
Arrays.asList(arr); // 将数组转换为集合,是一个受限集合,不能添加和删除元素 // 将基本类型数组转换为集合时,需要修改为包装类 Integer[] nums = {100,200,300,400,500}; Listlist = Arrays.asList(nums);
void reverse(List> list) // 反转集合中元素的顺序
-
public static void shuffle(List> list) // 随机重置集合元素的顺序
-
public static void sort(List list) // 升序排序(元素类型必须实现Comparable接口)
-
// binarySearch二分查找(要求集合事先必须是有序的),找出所需元素。
Integer[] arr = list.toArray(new[0] Interger); // 将集合list转换成数组arr
-
Arrays.asList(arr); // 将数组转换为集合,是一个受限集合,不能添加和删除元素 // 将基本类型数组转换为集合时,需要修改为包装类 Integer[] nums = {100,200,300,400,500}; Listlist = Arrays.asList(nums);
-



