数组的缺陷
数组长度固定不变
不便存储具有映射关系的数据
数据变更效率低下
如果并不知道程序运行时会需要多少对象,或者需要更复杂方式存储对象,可以使用Java集合框架
Java 集合框架提供了一套性能优良、使用方便的接口和类,位于java.util包中,集合中的元素全部是对象,即Object类的实例,不同的集合类有不同的功能和特点,适合不同的场合
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WZtRIz7m-1676512863744)(./assets/%E9%9B%86%E5%90%88%E6%A1%86%E6%9E%B6.jpg)]
Collection 接口存储一组不唯一,无序的对象
Map接口存储一组键值对象,提供key到value的映射
名称 | 描述 |
---|---|
Collection | ● 单个值集合的根接口,最基本的集合接口 ● 一个 Collection 代表一组 Object (对象)。Java不提供实现类,只提供子接口( List 接口和 Set 接口) ● Collection 接口存储一组可重复的无序对象 |
Set | ● 继承 Collection 接口,存储一组不可重复的无序对象 |
List | ● 继承 Collection 接口,存储一组可重复的有序对象 ● 元素顺序以元素插入的次序来放置元素,不会重新排序 ● 通过索引访问数组,索引从0开始 ● List 接口常用的实现类有 ArrayList 类和 LinkedList 类 |
Map | ● 存储成对数据的根接口,可存储一组" key(键)-value(值对)"对象 ● 提供 key(键) 到 value(值) 的映射 ● Map 中的 key(键) 是无序的,不重复的 ● Map 中的 value(值) 是无序的,可重复的 ● 可以通过 key(键) 找到对应的 value(值) |
Iterator | ● 集合迭代器,可以遍历集合元素的接口 |
Collections | ● 与 Collection 是不同的概念,它提供了对象合对象进行基本操作的通用接口方法 ● 包含各种有关集合操作的静态方法 ● 工具类,不可实例化 |
Collection 接口是 List、Set 接口的父接口,该接口里定义的方法既可用于操作 Set 集合,也可用于操 作List 集合
方法 | 描述 |
---|---|
boolean add(Object o) | 用于向集合中添加一个元素 如果集合不允许重复且已包含了指定元素,则返回false |
boolean addAll(Collection c) | 将集合c里所有元素添加到指定集合里。添加成功返回true |
void clear() | 清除集合中所有元素,将集合长度变为为0 |
boolean contains(Object o) | 判断集合中是否包含指定元素 |
boolean containsAll(Collection c) | 判断集合中是否包含集合c里所有的元素 |
boolean remove(Object o) | 删除集合中的指定元素o。当集合中包含了一个或多个元素o时,这些元素将被删除。删除成功,返回true |
int size() | 返回集合里元素的个数 |
boolean retainAll(Collection c) | 从集合中删除集合c里不包含的元素(相当于把调用该方法的集合变成该集合和集合c的交集) 如果该操作改变了调用该方法的集合,则返回true |
boolean removeAll(Collection c) | 从集合中删除集合c里包含的所有元素 如果删除了一个或一个以上的元素,则返回true |
boolean isEmpty() | 如果此集合中不包含任何元素,则返回true |
Object[] toArray() | 该方法把集合转换成一个数组,所有的集合元素变成对应的数组元素 |
Collection list=new ArrayList();
//使用 ArrayList 对象
// ArrayList 是 List 的实现类
Collection set=new HashSet();
//使用 HashSet 对象
// HashSet 是 Set 的实现类
集合中存储元素为Object类型对象,属于引用数据类型,默认调用Object类toString()方法执行输出操作,输出集合元素时,调用String类重写的toString()方法
当时用 System.out.println() 方法输出集合时,将以[ele1,ele2,…]的形式输出,这是因为所有的 Collection 实现类都重写了 toString() 方法,该方法可以一次性输出集合里的每一个元素,如果想依次访问集合元素,并对其进行操作,则需要遍历集合元素
Iterator接口定义的方法
方法 | 描述 |
---|---|
boolean hasNext() | 是否存在下一个迭代元素,存在则返回true |
Object next() | 返回迭代的下一个元素 |
void remove() | 删除集合里上一次next()方法返回的元素 |
Iterator 接口对元素进行遍历时,是把集合元素的值传给了迭代器,所以修改迭代器中存储的值,对集合元素本身没有任何影响
for(数据类型 迭代变量名 : 迭代对象){
//引用迭代变量名的语句
}
foreach 循环中的迭代变量也不是集合元素本身,系统只是把集合元素付给了迭代变量,因此,在 foreach 循环中修改迭代变量的值也没有任何实际意义
package CH07_Collection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class MyIterator {
public static void main(String[] args) {
Collection list = new ArrayList();
list.add("玄子");
list.add("XuanZiShaer");
list.add("玉玉诏");
list.add("QQ:3336392096");
System.out.println("------println-------");
System.out.println(list);
System.out.println("------Iterator------");
Iterator iterator = list.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
System.out.println("-----ForEach--------");
for (Object o : list) {
System.out.println(o);
}
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-csEmauMP-1676512863748)(./assets/%E6%90%9C%E7%8B%97%E6%88%AA%E5%9B%BE20230216081931.png)]
foreach:在遍历集合时不能对集合进行操作
Iterator:在遍历集合时可以对集合进行操作,他是将自己的数据传给了 iterator 迭代器
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jUrAaN7T-1676512863749)(./assets/image-20230216085402344.png)]
方法 | 描述 |
---|---|
void add(int index,Object element) | 将元素(element)插入到List的指定位置(index)处 |
boolean addAll(int index,Collection c) | 将集合c所包含的所有元素都插入List集合指定位置(index)处 |
Object get(int index) | 返回集合index索引处的元素 |
int indexOf(Object o) | 返回对象o在List集合中第一次出现的位置索引 |
int lastIndexOf(Object o) | 返回对象o在List集合中最后一次出现的位置索引 |
Object remove(int index) | 从集合中删除指定位置的元素 |
boolean remove(Object o) | 从集合中删除指定对象 |
Object set(int index,Object element) | 将index索引处的元素替换成element对象,返回新元素 |
List subList(int fromIndex,int toIndex) | 返回从索引fromIndex(包含)到索引toIndex(不包含)处所有集合元素组成的子集合 |
List 接口常用的子类有 ArrayList 类 和 LinkedList 类
List list = new ArrayList();
List list2 = new LinkedList();
使用 List 接口的扩展方法,需要通过 List 接口的实现类实例化对象调用
可以使用索引访问 List 集合元素
可以使用 for 循环遍历 List 集合
List 集合中存放的都是 Object 类对象
add(Object o)方法的参数是Object类对象
在通过get(int i)方法获取元素时必须进行强制类型转换
删除集合元素的方法
按索引删除
按对象删除
调用set(int index,Object o)方法改变List集合指定索引的元素时,指定的索引必须是List集合的有效索引
set(int index,Object o)方法不会改变List集合的长度
package CH07_Collection.List;
import java.util.ArrayList;
import java.util.List;
public class MyArrayList {
public static void main(String[] args) {
List list = new ArrayList();
list.add("XuanZi");
list.add("玄子");
list.add(123);
list.add(true);
list.add('男');
list.add(new Student("玄子", 18));
// 添加元素
System.out.println(list);
// 打印集合元素
list.remove("XuanZi");
// 移除元素
System.out.println(list);
boolean iscont = list.contains("XuanZi");
// 是否含有元素
System.out.println(iscont);
int index = list.indexOf("玄子");
// 查找元素下标
System.out.println(index);
list.set(1, "456");
// 替换元素 下标 元素
System.out.println(list);
Object obj = list.get(2);
// 获取元素 下标
System.out.println(obj);
System.out.println(list.subList(2, 4));
// 截取元素 起始下标(包含) 结束下标(不包含)
System.out.println(list);
for (Object o : list) {
System.out.println(o);
}
// foreach 打印集合元素
list.clear();
// 清空元素
System.out.println(list);
}
}
LinkedList
类随机访问元素的速度则相对较慢方法 | 描述 |
---|---|
void addFirst(Object o) | 在链表的首部添加元素 |
void addLast(Object o) | 在链表的末尾添加元素 |
Object getFirst() | 返回链表中第一个元素 |
Object getLast() | 返回链表中最后一个元素 |
Object removeFirst() | 删除并返回链表中的第一个元素 |
Object removeLast() | 删除并返回链表中的最后一个元素 |
LinkedList 特有的方法 必须是LinkedList 类型的集合才可以使用,如果是父类,则无法调用
LinkedList list=new LinkedList();
// 通过 LinkedList 类实现
list.addFirst("第一位");
ArrayList 类和 LinkedList 类的共同点
可以容纳所有类型的元素对象,包括null
元素值可以重复
元素按顺序存储
ArrayList 类特点
底层是数组
优点:基于数组实现,读取操作效率高
缺点:不适合频繁进行插入和删除操作,因为每次执行该类操作都需要频繁移动其中的元素
LinkedList 类特点
由双向链表实现,任意一个节点都可以方便地访问它的前驱节点和后继节点
优点:增加、删除操作只需修改链表节点指针,不需进行频繁的移动
缺点:遍历效率较低
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-G4yzzj5C-1676512863749)(./assets/image-20230216085227374.png)]
特征
不允许存储重复的元素
没有索引,没有包含索引的方法,不能使用索引遍历
无序集合,存储元素和取出元素的顺序可能不一致
执行添加操作时,会将新添加的对象依次和集合中现有的元素进行比较
通过执行集合元素的hascode()方法和equals()方法进行判断
如果集合中不存在所添加的元素,则添加成功;否则,添加失败
package CH07_Collection.Set;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class MyHashSet {
public static void main(String[] args) {
Set set = new HashSet();
set.add("玄子");
set.add("玄子1");
set.add("玄子2");
set.add("玄子3");
set.remove("玄子");
System.out.println(set.size());
Iterator iterator = set.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
System.out.println(set.contains("玄子"));
set.clear();
System.out.println(set.isEmpty());
}
}
Map接口专门处理键值映射数据的存储
根据键(key)实现对值(value)的操作
Key:不要求有序,不允许重复
Value:不要求有序,但允许重复
与Collection接口不存在继承关系
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wvOqa6U8-1676512863750)(./assets/image-20230216091119798.png)]
方法 | 描述 |
---|---|
Object put(Object key,Object value) | 以“键-值对”的方式进行存储 |
Object get(Object key) | 返回指定键所对应的值。如果不存在指定的键,返回null |
int size() | 返回元素个数 |
boolean remove(Object key) | 删除指定的键映射的“键-值对” |
Set keyset() | 返回键的集合 |
Collection values() | 返回值的集合 |
boolean containsKey(Object key) | 如果存在指定的键映射的“键-值对”,则返回true |
Set entrySet() | 返回“键-值对”集合 |
boolean isEmpty() | 若不存在“键-值对”元素,则返回true |
void clear() | 删除该Map对象中的所有“键-值对” |
Map 接口提供了大量的实现类,典型实现类如 HashMap 类、HashTable 类、TreeMap 类等,其中 HashMap 类是最常用的 Map 接口实现类
package CH07_Collection.Map;
import java.util.*;
public class MyMap {
public static void main(String[] args) {
Map map = new HashMap();
// 创建Map集合
map.put("一", "玄子");
map.put("二", "玉玉诏");
map.put("三", "XuanZi");
map.put("四", "XuanZiShaer");
// 给集合里添加数据
System.out.println(map.get("二"));
// 根据提供的key值返回value值
System.out.println(map.size());
// 元素个数
System.out.println(map.remove("三"));
// 根据提供的kye值删除元素
System.out.println(map.containsKey("四"));
// 判断是否存在映射的键-值对
map.clear();
// 清除集合所有元素
System.out.println(map.isEmpty());
}
}
package CH07_Collection.Map;
import java.util.*;
public class MyMap {
public static void main(String[] args) {
Map map = new HashMap();
// 创建Map集合
map.put("一", "玄子");
map.put("二", "玉玉诏");
map.put("三", "XuanZi");
map.put("四", "XuanZiShaer");
// 给集合里添加数据
System.out.println("-----遍历Map-----");
Set set = map.keySet();
Iterator iterator = set.iterator();
while (iterator.hasNext()) {
Object key = iterator.next();
System.out.println(key);
System.out.println(map.get(key));
}
System.out.println("------------");
for (Object o : set) {
System.out.println(o + map.get(o).toString());
}
System.out.println("------------");
Set set1 = map.entrySet();
for (Object o : set1) {
System.out.println(o);
}
System.out.println("------------");
Collection collection = map.values();
for (Object o : collection) {
System.out.println(o.toString());
}
System.out.println("------------");
}
}
Set集合中每个元素都是一个Map.Entry对象,进行键和值的分离,由于是Object类型,在获取对象之前还需要进行必要的类型转换
用于保存“键-值对”元素
运用Map.Entry接口遍历集合
通过entrySet()方法获取所有“键-值”对元素的集合
遍历集合中每个元素,进行键和值的分离
方法 | 描述 |
---|---|
Object getKey() | 取得此“键-值对”对应的key值 |
Object getValue() | 取得此“键-值对”相对应的value值 |
int hashCode() | 返回该“键-值对”的哈希码值 |
Object setValue(Object value) | 用指定的值替换该“键-值对”的value值 |
与HashMap类具有相似的特征,也可以存储“键-值对”元素,是一个古老的Map接口实现类
Hashtable | HashMap |
---|---|
继承自 Dictionary 类 | Java1.2引进的 Map interface 的一个实现 |
比 HashMap 要古老 | 是 Hashtable 的轻量级实现 |
线程安全 | 线程不安全 |
不允许有 null 的键和值 | 允许有 null 的键和值 |
效率稍低 | 效率稍高 |
实际开发中,HashMap类使用更多
使用集合存储数据时容易出现的问题
对象存储不易控制
类型转换容易出错
约束录入集合的元素类型,大大提高数据安全性,从集合中取出数据无需进行类型转换,让代码更加简洁,程序更加健壮,JDK1.5使用泛型改写了集合框架中的所有接口和类
集合类型 <要规范的类型> 集合名=new 集合类型 <要规范的类型>();
public class Test03 {
public static void main(String[] args) {
List<Integer> list=new ArrayList<Integer>();
//集合内只可以存储 Integer 对象
list.add(1);
list.add(2);
list.add(3);
//因为已经设置了泛型,所以不需要再转换类型
int num= list.get(1);
}
}
BCSP-玄子JAVA开发之面向对象编程CH07_ 集合框架笔记 2.16