前言
Java是面向对象的语言,我们在编程的时候自然需要存储对象的容器,数组可以满足这个需求,但是数组初始化时长度是固定的,但是我们往往需要一个长度可变化的容器,因此,集合出现了。
1. Collection集合
1.1 集合体系结构
-
集合类的特点
提供一种存储空间可变的存储模型,存储的数据容量可以随时发生变化。
-
集合的体系图
1.2 Collection集合概述和基本使用
1.2.1 Collection集合概述
- 是单例集合的顶层接口,它表示一组对象,这些对象也称为Collection的元素
- JDK 不提供此接口的任何直接实现,它提供更具体的子接口(如Set和List)实现
1.2.2 Collection集合说明
- Collection是一个接口,是高度抽象的集合,它包含了集合的基本操作:对集合元素的增、删、改、查、判断是否为空,获取大小、遍历等操作;
- 根据Collection接口规范的建议:Collection接口的所有子类(直接子类和间接子类)都必须实现2种构造函数:不带参数的构造函数 和 参数为Collection的构造函数。
1.2.3 Collection集合基本使用
public class CollectionDemo {
public static void main(String[] args) {
//创建Collection集合的对象
Collection<String> c = new ArrayList<String>();
//添加元素:boolean add(E e)
c.add("hello");
c.add("world");
c.add("java");
//输出集合对象
System.out.println(c);
}
}
1.3 Collection集合的常用方法以及遍历演示
1.3.1 Collection的常用方法
方法名 | 说明 |
---|---|
boolean add(E e) | 添加元素 |
boolean remove(Object o) | 从集合中移除指定的元素 |
void clear() | 清空集合中的元素 |
boolean contains(Object o) | 判断集合中是否存在指定的元素 |
boolean isEmpty() | 判断集合是否为空 |
int size() | 集合的长度,集合中元素的个数 |
1.3.2 Collection集合遍历
-
迭代器:
- 集合的专用遍历方式
- iterator iterator(): 返回此集合中元素的迭代器,通过集合的iterator() 方法得到。
- 迭代器是通过集合的iterator()方法得到的,所以我们说它是依赖于集合而存在的
-
遍历集合的方法
(1)将集合转成数组,遍历数组(不常用)
(2)迭代器遍历(创建迭代器对象,用while循环调用hasnext()方法判断下一个元素是否存在,然后调用迭代器的next()方法)
(3)用foreach直接进行遍历 —格式:for(数据类型 变量名:要遍历的集合名){ 直接输出变量;}
示范代码:
//创建集合对象
Collection<String> c = new ArrayList<>();
//Iterator<E> iterator():返回此集合中元素的迭代器,通过集合的iterator()方法得到
Iterator<String> it = c.iterator();
//用while循环改进元素的判断和获取
while (it.hasNext()) {
String s = it.next();
System.out.println(s);
}
2. list集合
2.1 List 集合概述
- 有序集合(也称为序列),用户可以精确控制列表中每个元素的插入位置。用户可以通过整数索引访问元素,并搜索列表中的元素
- 与Set集合不同,列表通常允许重复的元素
2.2 List集合特点
- List集合说明
- List接口继承Collection接口,实现了List接口的类称为List集合。
- 在List集合中允许出现重复的元素,所有元素以线性方式进行存储,可以通过索引来访问集合中指定的元素。List集合的元素的存储顺序和取出顺序一致。
- List不但继承了Collection接口中的全部方法,还增加了一些根据元素位置索引来操作集合的特有方法。
注意: 集合不能定义为基本数据类型(int、char、float……),应该定义为包装类数据类型(Integer、String……)。
2.3 List集合特有方法
方法名 | 描述 |
---|---|
void add(int index,E element) | 在此集合中的指定位置插入指定的元素 |
E remove(int index) | 删除指定索引处的元素,返回被删除的元素 |
E set(int index,E element) | 修改指定索引处的元素,返回被修改的元素 |
E get(int index) | 返回指定索引处的元素 |
2.4 列表迭代器
-
ListIterator介绍
- 通过List集合的listIterator()方法得到,所以说它是List集合特有的迭代器
- 用于允许程序员沿任一方向遍历的列表迭代器,在迭代期间修改列表,并获取列表中迭代器的当前位置
示范代码:
public class ListIteratorDemo { public static void main(String[] args) { //创建集合对象 List<String> list = new ArrayList<String>(); //添加元素 list.add("hello"); list.add("world"); list.add("java"); //获取列表迭代器 ListIterator<String> lit = list.listIterator(); while (lit.hasNext()) { String s = lit.next(); if(s.equals("world")) { lit.add("javaee"); } } System.out.println(list); } }
2.5 增强for循环
定义格式:
for(元素数据类型 变量名 : 数组/集合对象名) {
循环体;
}
示范代码:
//创建集合对象
List<String> list = new ArrayList<String>();
...
for(String s: list){
System.out.println(s);
}
2.6 List集合的实现类
2.6.1 ArrayList 集合
底层是数组结构实现,查询快、增删慢
ArrayList 的三种遍历方式演示
示范代码:
public class ArrayListDemo{
public static void main(String[] args) {
//创建集合对象
List<String> list = new ArrayList<String>();
...
//1.迭代器:集合特有的遍历方法
Iterator it=list.iterator();
while(it.hashNext()){
String s=it.next();
System.out.println(s);
}
//2.普通for:带有索引的遍历方式
for(int i=0;i<list.size();i++){
String s=it.get(i);
System.out.println(s);
}
//3.增强for:最方便的遍历方式
for(String s:list){
System.out.println(s);
}
}
}
2.6.2 LinkList 集合
底层是链表结构实现,查询慢、增删快
LinkedList 集合的特有功能
方法名 | 说明 |
---|---|
public void addFirst(E e) | 在该列表开头插入指定的元素 |
public void addLast(E e) | 将指定的元素追加到此列表的末尾 |
public E getFirst() | 返回此列表中的第一个元素 |
public E getLast() | 返回此列表中的最后一个元素 |
public E removeFirst() | 从此列表中删除并返回第一个元素 |
public E removeLast() | 从此列表中删除并返回最后一个元素 |
3. Set集合
Set集合中的元素是无序的且不可重复, 如果试图把两个相同元素加入同一个Set集合中,则添加操作失败,add()方法返回false,且新元素不会被加入。
3.1 Set集合特点和基础使用
- 元素存取无序
- 没有索引,只能通过迭代器或增强for循环遍历
- 不能存储重复元素
Set集合的基础使用:
public class SetDemo {
public static void main(String[] args) {
//创建集合对象
Set<String> set = new HashSet<String>();
//添加元素
set.add("hello");
set.add("world");
set.add("java");
//不包含重复元素的集合
set.add("world");
//遍历
for(String s : set) {
System.out.println(s);
}
}
}
3.2 HashSet 类
HashSet底层数据结构是哈希表
,因此具有很好的存取和查找性能。
哈希表
:一个元素为链表的数组,综合了链表(存储速度快)和数组(查询速度快)的优点。
3.2.1 哈希值
-
哈希值简介
是JDK根据对象的地址或者字符串或者数字算出来的int类型的数值
-
如何获取哈希值
Object类中的public int hashCode():返回对象的哈希码值
-
哈希值的特点
- 同一个对象多次调用hashCode()方法返回的哈希值是相同的
- 默认情况下,不同对象的哈希值是不同的。而重写hashCode()方法,可以实现让不同对象的哈希值相同
3.2.2 哈希表的存取原理
-
调用对象的hashCode()方法,获得要存储元素的哈希值。
-
将哈希值与表的长度(即数组的长度)进行求余运算得到一个整数值,该值就是新元素要存放的位置(即是索引值)。
- 如果索引值对应的位置上没有存储任何元素,则直接将元素存储到该位置上。
- 如果索引值对应的位置上已经存储了元素,则执行第3步。
-
遍历该位置上的所有旧元素,依次比较每个旧元素的哈希值和新元素的哈希值是否相同。
- 如果有哈希值相同的旧元素,则执行第4步。
- 如果没有哈希值相同的旧元素,则执行第5步。
-
比较新元素和旧元素的地址是否相同
如果地址值相同则用新的元素替换老的元素。停止比较。
如果地址值不同,则新元素调用equals方法与旧元素比较内容是否相同。- 如果返回true,用新的元素替换老的元素,停止比较。
- 如果返回false,则回到第3步继续遍历下一个旧元素。
-
说明没有重复,则将新元素存放到该位置上并让新元素记住之前该位置的元素。
3.3 HashSet特点
- 对集合的迭代顺序不作任何保证,也就是说不保证存储和取出的元素顺序一致
- 集合中的元素值可以是null
- 底层数据结构是哈希表
- 没有带索引的方法,所以不能使用普通for循环遍历
- 由于是Set集合,所以是不包含重复元素的集合
- hashSet不是同步的,如果多个线程同时访问一个Set,只要有一个线程修改了Set中的值,就必须进行同步处理,通常通过同步封装这个Set对象来完成同步,如果不存在这样的对象,可以使用Collections.synchronizedSet()方法完成。
HashSet 集合的基本使用
public class HashSetDemo {
public static void main(String[] args) {
//创建集合对象
HashSet<String> hs = new HashSet<String>();
//添加元素
hs.add("hello");
hs.add("world");
hs.add("java");
hs.add("world");
//遍历
for(String s : hs) {
System.out.println(s);
}
}
}
3.4 LinkedHashSet集合概述和特点
- LinkedHashSet 集合特点
- 哈希表和链表实现的Set接口,具有可预测的迭代次序
- 由链表保证元素有序,也就是说元素的存储和取出顺序是一致的
- 由哈希表保证元素唯一,也就是说没有重复的元素
LinkedHashSet集合基本使用:
public class LinkedHashSetDemo {
public static void main(String[] args) {
//创建集合对象
LinkedHashSet<String> linkedHashSet = new LinkedHashSet<String>(); //添加元素
linkedHashSet.add("hello");
linkedHashSet.add("world");
linkedHashSet.add("java");
linkedHashSet.add("world");
//遍历集合
for(String s : linkedHashSet) {
System.out.println(s);
}
}
}
3.5 TreeSet 集合概述和特点
- TreeSet集合概述
- 元素有序,可以按照一定的规则进行排序,具体排序方式取决于构造方法
- TreeSet():根据其元素的自然排序进行排序
- TreeSet(Comparator comparator) :根据指定的比较器进行排序
- 没有带索引的方法,所以不能使用普通for循环遍历
- 由于是Set集合,所以不包含重复元素的集合
- 元素有序,可以按照一定的规则进行排序,具体排序方式取决于构造方法
TreeSet集合基本使用:
public class TreeSetDemo {
public static void main(String[] args) {
//创建集合对象
TreeSet<Integer> ts = new TreeSet<Integer>();
//添加元素
ts.add(10);
ts.add(40);
ts.add(30);
ts.add(50);
ts.add(20);
ts.add(30);
//遍历集合
for(Integer i : ts) {
System.out.println(i);
}
}
}
TreeSet可以确保集合元素处于排序状态。TreeSet支持两种排序方法:自然排序和定制排序。
4. Map集合
Map 是一种键-值对(key-value)集合,Map 集合中的每一个元素都包含一个键对象和一个值对象。其中,键对象不允许重复,而值对象可以重复,并且值对象还可以是 Map 类型的,就像数组中的元素还可以是数组一样。
4.1 Map集合概述
interface Map<K,V> K:键的类型 V:值的类型
Map集合的基本使用:
public class MapDemo {
public static void main(String[] args) {
//创建集合对象
Map<String,String> map = new HashMap<String,String>();
//V put(K key, V value) 将指定的值与该映射中的指定键相关联
map.put("zy01","张三");
map.put("zy02","李四");
map.put("zy03","王五");
//输出集合对象
System.out.println(map);
}
}
4.2 Map集合基本功能
方法名 | 说明 |
---|---|
V put(K key,V value) | 添加元素 |
V remove(Object key) | 根据键删除键值对元素 |
void clear() | 移除所有的键值对元素 |
boolean containsKey(Object key) | 判断集合是否包含指定的键 |
boolean containsValue(Object value) | 判断集合是否包含指定的值 |
boolean isEmpty() | 判断集合是否为空 |
int size() | 集合的长度,也就是集合中键值对的个数 |
示例代码:
public class MapDemo {
public static void main(String[] args) {
//创建集合对象
Map<String,String> map = new HashMap<String,String>();
...
//V remove(Object key):根据键删除键值对元素
System.out.println(map.remove("张三"));
//void clear():移除所有的键值对元素
map.clear();
//boolean containsKey(Object key):判断集合是否包含指定的键
System.out.println(map.containsKey("李四"));
//boolean isEmpty():判断集合是否为空
System.out.println(map.isEmpty());
//int size():集合的长度,也就是集合中键值对的个数
System.out.println(map.size());
}
4.3 Map集合的获取功能
方法介绍:
方法名 | 说明 |
---|---|
V get(Object key) | 根据键获取值 |
Set keySet() | 获取所有键的集合 |
Collection values() | 获取所有值的集合 |
Set<Map.Entry<K,V>> entrySet() | 获取所有键值对对象的集合 |
示例代码:
public class MapDemo {
public static void main(String[] args) {
//创建集合对象
Map<String,String> map = new HashMap<String,String>();
...
//V get(Object key):根据键获取值
System.out.println(map.get("张三"));
//Set<K> keySet():获取所有键的集合
Set<String> keySet = map.keySet();
for(String key : keySet) {
System.out.println(key);
}
//Collection<V> values():获取所有值的集合
Collection<String> values = map.values();
for(String value : values) {
System.out.println(value);
}
}
}
5. Collection集合工具类
Collections 概述和使用
-
Collections类的作用
是针对集合操作的工具类
-
Collections类常用方法
方法名 | 说明 |
---|---|
public static void sort(List list) | 将指定的列表按升序排序 |
public static void reverse(List<?> list) | 反转指定列表中元素的顺序 |
public static void shufflfflffle(List<?> list) | 使用默认的随机源随机排列指定的列表 |
示例代码:
public class CollectionsDemo {
public static void main(String[] args) {
//创建集合对象
List<Integer> list = new ArrayList<Integer>();
//添加元素
list.add(30);
list.add(20);
list.add(50);
list.add(10);
list.add(40);
//public static <T extends Comparable<? super T>> void sort•(List<T> list):将指定的列表按升序排序
Collections.sort(list);
//public static void reverse•(List<?> list):反转指定列表中元素的顺序
Collections.reverse(list);
//public static void shuffle•(List<?> list):使用默认的随机源随机排列指定列表
Collections.shuffle(list);
System.out.println(list);
}
}