基于java集合中的一些易混淆的知识点(详解)
作者:jingxian 时间:2023-08-29 03:06:26
(一) collection和collections
这两者均位于java.util包下,不同的是:
collection是一个集合接口,有ListSet等常见的子接口,是集合框架图的第一个节点,,提供了对集合对象进行基本操作的一系列方法。
常见的方法有:
boolean add(E e) 往容器中添加元素;int size() 返回collection的元素数;boolean isEmpty() 判断此容器是否为空; boolean contains(Object o) 如果此collection包含指定的元素,则返回true,,这里会用到equals()方法;boolean remove(Object o) 移除指定元素的实例;等。
而collections是一个包装类,它包含有各种有关集合操作的静态多态方法,它包含在 collection 上操作的多态算法,即“包装器”,包装器返回由指定 collection 支持的新 collection,以及少数其他内容。
常见的方法有:
void sort(List) 对List的内容进行排序。
这里要注意的是,(ps:以下有关sort()的说明摘自浅谈对象数组或list排序及Collections排序原理,对List及Collection排序追本溯源,写得很清晰)
这个sort()函数中的排序主体是Arrays.sort(),
@SuppressWarnings("unchecked")
public static <T extends Comparable<? super T>> void sort(List<T> list) {
Object[] array = list.toArray();
Arrays.sort(array);
int i = 0;
ListIterator<T> it = list.listIterator();
while (it.hasNext()) {
it.next();
it.set((T) array[i++]);
}
}
而Arrays.sort()中,可以看出是通过ComparableTimSort.sort(Object[] a)实现的:
public static void sort(Object[] array) {
// BEGIN android-changed
ComparableTimSort.sort(array);
// END android-changed
}
static void sort(Object[] a)到static void sort(Object[] a, int lo, int hi)到private static void binarySort(Object[] a, int lo, int hi, int start)。在binarySort中用于大小比较部分为:
Comparable<Object> pivot = (Comparable) a[start];
int left = lo;
int right = start;
assert left <= right;
while (left < right) {
int mid = (left + right) >>> 1;
if (pivot.compareTo(a[mid]) < 0)
right = mid;
else
left = mid + 1;
}
二分查找中比较大小部分使用了Comparable接口的唯一一个方法:compareTo(),所有如果自定义的类装载到容器中需要进行比较的时候,要实现Comparable接口或继承Comparator类,并重写compareTo()方法。
int binarySearch(List object) 对于顺序的List容器,采用折半查找法查找指定对象;void reverse(List) 对List的容器内的对象进行逆序排列;等。
(二)Iterator和Iterable
首先,Iterable位于java.lang包下,Iterator位于java.util包下。在集合框架中,Iterator接口中定义了一下三个方法:boolean hasNext();E next();void remove()。而Iterable中只定义了一个方法:iterator(),返回值为实现了Iterator接口的的一个对象。Collection继承了Iterable这个超级接口,故所有的集合框架中的实现类都具有iterator()这个方法,而多态让Iterator的引用可以访问到当前集合中实现了Iterator的那部分(即那三个方法)。此时如果需要删除元素,由于Iterator对这个集合操作时完成了锁定,在用Iterator循环遍历的过程中只能使用Iterator的remove()方法,而不能使用Collection自己的remove(Object)方法。
那么为什么一定要实现Iterable接口,为什么不直接实现Iterator接口呢,这样就可以让集合类直接继承这三个方法?
看一下JDK中的集合类,比如List一族或者Set一族,都是实现了Iterable接口,但并不直接实现Iterator接口。
仔细想一下这么做是有道理的。
因为Iterator接口的核心方法next()或者hasNext() 是依赖于迭代器的当前迭代位置的。
如果Collection直接实现Iterator接口,势必导致集合对象中包含当前迭代位置的数据(指针)。
当集合在不同方法间被传递时,由于当前迭代位置不可预置,那么next()方法的结果会变成不可预知。
除非再为Iterator接口添加一个reset()方法,用来重置当前迭代位置。
但即时这样,Collection也只能同时存在一个当前迭代位置。
而Iterable则不然,每次调用都会返回一个从头开始计数的迭代器。
多个迭代器是互不干扰的。
![](/images/zang.png)
![](/images/jiucuo.png)
猜你喜欢
Java运行时数据区域(内存划分)的深入讲解
![](https://img.aspxhome.com/file/2023/8/94298_0s.png)
c# 使用handle.exe解决程序更新文件被占用的问题
AndroidStudio插件GsonFormat之Json快速转换JavaBean教程
![](https://img.aspxhome.com/file/2023/5/137325_0s.jpg)
详解MyBatis的Dao层实现和配置文件深入
![](https://img.aspxhome.com/file/2023/6/61246_0s.jpg)
详解Java编程中线程同步以及定时启动线程的方法
JAVA熔断和降级真实关系的图文详解
![](https://img.aspxhome.com/file/2023/7/67957_0s.png)
Android开机画面的具体修改方法
java 遍历request中的所有表单数据的实例代码
Java编写简单猜数游戏
![](https://img.aspxhome.com/file/2023/6/79226_0s.jpg)
C#使用foreach语句遍历堆栈(Stack)的方法
C#实现无损压缩图片代码示例
java与c#的语法区别详细介绍
Android不显示开机向导和开机气泡问题
![](https://img.aspxhome.com/file/2023/0/123310_0s.jpg)
WinForm绘制圆角的方法
如何实现bean初始化摧毁方法的注入
![](https://img.aspxhome.com/file/2023/8/83588_0s.jpg)
Android应用内悬浮窗Activity的简单实现
![](https://img.aspxhome.com/file/2023/4/84704_0s.png)
MyBatis-Plus 集成动态多数据源的实现示例
Java登录功能实现token生成与验证
![](https://img.aspxhome.com/file/2023/6/94236_0s.jpg)
SpringCloud版本问题报错及解决方法
![](https://img.aspxhome.com/file/2023/1/61561_0s.png)
Android—基于微信开放平台v3SDK开发(微信支付填坑)
![](https://img.aspxhome.com/file/2023/6/137346_0s.png)