- 什么是集合框架
- 存储任意数量对象的容器(只能存储引用数据类型)
- 能称为框架,说明这内容很多
- 实质:都是一些工具包
图解,这就是集合框架
- 虚线框:接口或抽象类
- 实现框:普通类
- 箭头:表示实现接口或继承抽象类或继承接口
- 说明:Collection并非继承了Iterator接口而是继承了Iterable接口
1) Iterable接口中定义了获取迭代器的方法,由其实现类实现了
2) Iterator接口是在java.util包中
3) 图解
- 存储任意数量对象的容器(只能存储引用数据类型)
- 集合框架的作用
- 同数组一样,用于存储多个数据,但它更方便
- 数组的长度固定,集合长度可变
- 数组只能通过映射获取数组中的数据,而集合可以使用键来获取值
- 同数组一样,用于存储多个数据,但它更方便
- 使用集合框架
- 了解常用各层次的关系与作用
- 关系说明(全部来于,java.util包)
1)
2)
- 关系说明(全部来于,java.util包)
- Collection接口下的List与Set
- 父级接口Collection定义的常用方法(都是通用的)
增
add(obj);//添加一个元素,下标为0,其后依次增加,同数组添加元素的过程
add(int index,obj);//根据传入的下标添加指定的元素,其后元素右移
addAll(Collection c);//根据传入的集合添加元素
删
remove(int index);//根据下标删除对象,是直删除,其后元素前移
remove(Object obj);//根据传入的对象删除
removeAll(Collection c);//根据传入的集合删除对应的元素
clear()//清空所有元素,集合变成[],不是null
查
直接输出对象即可查看集合中存储的数据
seize();//获取元素个数
isEmpty();是否是0个元素
contains(object obj);//根据传入的对象判断是否存在
toArray();转换成对象数组
iterator();获取一个迭代器,它提供了一系列方法用来遍历集合的 子接口List:有序且可重复
实现类ArrayList:它还实现了其它接口,不仅有父接口的方法还有如下特有方法
改
set(int index,Object obj);//根据传入的下标设值(下标要合理),有下标范围检查,如果下标大于size会抛出异常:下标越界查 get(int index)//根据传入下标获取元素(下标要合理) indexOf(Object obj);//根据传入的对象判断第一次出现的索引 lastIndexOf(Object obj);//根据传入的对象判断最后一次出现的索引
实现类LinkedList:它还实现了其它接口,不仅有父接口的方法还有如下特有方法
增
addFirst(Object obj);//在链头添加对象
push(Object obj);//就是调用的上面方法addLast(Object obj);//在链尾添加对象 删 removeFirst();//移出链头 pop();//就是调用的上面方法 removeLast();//移出链尾 查 getFirst();//获取链头 getLast();//获取链尾
实现类Vector:用法同ArrayList
ArrayList与LinkedList的异同
异
前者
基于动态数组的数据结构
查找和修改性能高于后者(因为LinkedList要移动指针)
后者
基于链表的数据结构
新增删除高于前者(因为ArrayList要移动数据)
测试代码同 集合长度可变 只能存储引用数据类型 都是非同步的
ArrayList与Vector的异同
同:集合长度可变,只能存储引用数据类型
异
前者
方法不是同步的
ArrayList只增加50%的大小,这样,ArrayList就有利于节约内存空间
后者
方法都是同步的(Synchronized),是线程安全的(thread-safe)存储元素数量超过它的初始大小时,Vector会将它的容量翻倍
子接口Set:有时无序且不可重复
HashSet实现类
使用父接口的方法即可
常用TreeSet实现类
HashSet与TreeSet接口的异同
使用父接口的方法即可
使用较少,创建实例时必须指定排序规则,否则无法添加元素(cannot be cast to java.lang.Comparable)
同
两者中的值都不能重复
HashSet和TreeSet都是非同步
基本操作方法使用父接口即可
异
前者
基于HashMap实现
可以放入null,但只能放入一个null
哈希表实现的,数据是无序的
后者
基于TreeMap实现
不允许放入null值(null比较是没有意义的)
二差树实现的,可自定义排序规则
- 父级接口Collection定义的常用方法(都是通用的)
- Map接口下的HashMap,TreeMap,Hashtable,ConcurrentHashMap
- 父级接口Map定义的常用方法(都是通用的)
- 增
put(key,value);根据键值对的数据类型添加:键值 - 删
remove(key);根据传入的键删除对象的值,返回被删除 的对象:如果key不存在,不会报错,此时返回null - 改
replace(键,键的新值);修改键对应的值 查
可直接输出get(key);//根据键获取值
containsKey(key);//是否有该键
containsValue(value);//是否有该值
isEmpty();//是否是空
size();//键值对的个数
keySet();//获取键的集合
values();//获取值的集合
entrySet();//获取键值对集合,获取后可直接输出
- 增
- HashMap实现类:用Map接口中定义的方法即可
- TreepMap实现类:用Map接口中定义的方法即可
- Hashtable实现类:同上
- ConcurrentHashMap实现类:同上,JDK5以上使用此类代替Hashtable,它功能更强
- HashMap与TreeMap的异同
异
前者
基于哈希散列表实现
随机存储
无性能损耗,建议使用(效率高)
键、值可为null后者
哈希散列表实现
默认按键的升序排序
插入、删除有性能损耗
键、值都不能为null- 同
非并发安全Map
都是键值映射方式存储数据
- HashMap与Hashtable的异同
- 同:都是键值方式存储数据
异
前者
非并发(非同步,非线程安全);
键、值可为null后者
并发
键,值不可为null
- 父级接口Map定义的常用方法(都是通用的)
- 工具类(并非集合框架成员),参考
Collections
它是什么
它是用于操作集合的工具类,提供了很多操作集合的静态方法
如何使用它来操作集合
改
sort(List list),按自然排序的升序排序
swap(List list, int i , int j),交换两个索引位置的元素
boolean replaceAll(List list, Object oldVal, Object newVal), 用新元素替换旧元素
Collections中几乎对每个集合都定义了同步控制方法
SynchronizedList(), SynchronizedSet()等方法,来将集合包装成线程安全的集合
singleXXX(),返回一个只包含指定对象,只有一个元素,只读的集合
unmodifiablleXXX(),返回指定集合对象的只读视图
查
int binarySearch(List list, Object key), 对List进行二分查找,返回索引,注意List必须是有序的
int max(Collection coll),根据元素的自然顺序,返回最大的元素
int frequency(Collection c, Object o),统计元素出现次数
测试代码Arrays,参考 https://blog.csdn.net/daicooper/article/details/80951403 https://www.cnblogs.com/yj20hl/p/6083865.html
它是什么:用于操作数组的工具类
它的使用:都是使用静态方法
增
copyOf(数组,复制长度);//从数组中复制指定长度复制数组并返回,下标下0开始
copyOfRange(数组,开始,结束)//从数组中指定开始与结束下标复制数组并返回
改
fill(数组,值);//用一个指定的值填充数组
sort(数组);//默认升序排序
asList(数组)//返回一个包装数组的 List
asList.get(0)[0];//获取数组中的数据
查
toString(数组)//转换成字符串数据格式
deepToString(二维数组)//转换成字符串数据格式
binarySearch(数组,开始,结束,搜索的值)//指定范围与数组然后搜索特定值的下标
equals(数组)//使用的==比较
Arrays.toString(arr1).equals(Arrays.toString(arr3))//根据内容比较两个数组是否相等,前提是用相同的排序规则
测试代码
- Iterator迭代器
- 它是什么:用于遍历List集合的迭代器
- 使用它
- 用在while语句中遍历集合
Iterator it = 集合.iterator();//由集合获取迭代器:变量的初始化
while(it.hasNext(){//判断是否有下个元素:循环条件
类型 变量 = it.next();//获取集合中的每个元素:循环操作
} - 用在for语句中遍历集合
for(Itrator it = 集合.iterator();it.hasNext();){//同上,for把初始化,条件放一起了
类型 变量 = it.next();//获取集合中的每个元素:循环操作
} - 测试代码
- 说明
迭代器可对List的任何实现类进行遍历(无论有序还是无序),不能直接对Map遍历
List继承实现了Iterable接口(其中定义了获取迭代器的方法)
Map接口没有继承Iterable接口,且它没有定义获取迭代器的方法,但它的keySet,Values,entrySet是集合类型,因此可用迭代器操作
直接输出:System.out.println(hmap);//{key1=value1, key2=value2, key3=value3}
使用iterator遍历set集合
Set keySet = hmap.keySet();//获取键的集合
Iterator iterator = keySet.iterator();
for(;iterator.hasNext();){
String next = iterator.next();
System.out.println(next+"->"+hmap.get(next));//根据键获取值
}
使用iterator遍历entrySet集合
Set<Entry<String,String>> entrySet = hmap.entrySet();//获取键值组成的集合
Iterator<Entry<String, String>> iterator2 = entrySet.iterator();
for(;iterator2.hasNext();){
Entry<String, String> next = iterator2.next();
System.out.println(next.getKey()+"="+next.getValue());
}
测试代码在遍历集合时删除元素(倒数第二个除外),不能用集合的remove(obj或index)而要用迭代器的remove()方法
正确用法为什么用集合的remove(obj或index)要报错,而迭代器的remove()不会报错
根本原因:expectedModCount与modCount不同抛此异常iterator实例的remove方法与集合的remove()方法的区别
扩展理解
如果删除的元素是倒数第二个数的话,为何可用集合的remove()方法呢:简单的
- 用在while语句中遍历集合
- 了解常用各层次的关系与作用
- 说明
- 如何选择使用提高程序运行效率
- 如果元素个数是固定的推荐用数组
- 如果元素个数不是固定的推荐用集合
- 理解有序与无序
- 无序:没有排序规则
- 添加元素时的顺序与使用迭代器输出元素时的顺序不同即无序
- 有序:有排序规则
- 可与添加元素的顺序相同,或相反
- 无序:没有排序规则
- 遍历数组的几种方式
- while循环
变量的初始化
while(循环条件){
循环操作
} - for循环
for(变量的初始化;循环条件;变量的迭代){
循环操作
} - 增强for循环
for(类型 变量 : 数组名){
循环操作
}
- while循环
- 遍历集合的几种方式
- while循环+迭代器
根据集合获取它的迭代器
while(迭代器.hasNext()){
使用迭代器.next()的代码;//获取每个元素;
} - for循环+迭代器
for(根据集合获取它的迭代器;迭代器.hasNext();){//迭代器自动移动不需要写变量的迭代
使用迭代器.next()的代码;//获取每个元素;
} - 增强for循环
for(类型 变量 : 集合名){
循环操作
}- 隐藏的使用迭代器来遍历集合的
- 没有显示的iterator实例,遍历时不建议删除元素(只能用list.remove()-会报错的)
- 不要在 foreach 循环里进行元素的 remove/add 操作。remove 元素请使用 Iterator 方式
- while循环+迭代器
- 遍布map使用EntrySet集合,它效率高
- synchronized的使用方法:详细见后面
- 使用sychronized意味着在一次仅有一个线程能访问此方法,其它线程要等到同步锁被释放之后才能访问
- 多线程
- 如何选择使用提高程序运行效率
转载于:https://www.cnblogs.com/River111/p/9593306.html