温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Java源码解析之接口Collection的示例分析

发布时间:2021-05-20 09:27:36 来源:亿速云 阅读:169 作者:小新 栏目:开发技术

小编给大家分享一下Java源码解析之接口Collection的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

一、图示

Java源码解析之接口Collection的示例分析

二、方法定义

我们先想一想,公司如果要我们自己去封装一些操作数组或者链表的工具类,我么需要封装哪些功能呢?不妨就是统计其 大小,增删改查、清空或者是查看否含有某条数据等等。而collection接口就是把这些通常操作提取出来,使其更全面、更通用,那现在我们就来看看其源码都有哪些方法。

//返回集合的长度,如果长度大于Integer.MAX_VALUE,返回Integer.MAX_VALUE int size(); //如果集合元素总数为0,返回true boolean isEmpty(); //判断集合中是否包含指定的元素,其依据是equals()方法 boolean contains(Object o); //返回一个包含集合中所有元素的数组 Object[] toArray(); //与上个类似,只是增加了类型的转换 <T> T[] toArray(T[] a); //向集合中加入一个元素,如果成功加入则返回true,如果加入失败,或者因集合本身已经包含同个元素而不再加入时,返回false boolean add(E e); //从集合中删除指定元素的单个实例 boolean remove(Object o); //如果集合包含指定集合中的所有元素,返回true boolean containsAll(Collection<?> c); //把指定集合中的所有元素添加到集合中,但在此期间,如果指定的集合发生了改变,可能出现意想不到的事情 boolean addAll(Collection<? extends E> c); //从集合中删除所有包含在指定集合中的元素 boolean removeAll(Collection<?> c); //仅保留集合中包含在指定集合中的元素 boolean retainAll(Collection<?> c); //清空集合 void clear(); //将此方法抽象,是保证所有子类都覆写此方法,以保证equals的正确行为 boolean equals(Object o); //同上 int hashCode(); //这个方法在JDK1.8中提供了默认的实现,会使用Iterator的形式删除符合条件的元素 default boolean removeIf(Predicate<? super E> filter){     Objects.requireNonNull(filter);     boolean removed = false;     final Iterator<E> each = iterator();     while (each.hasNext()) {         if (filter.test(each.next())) {             each.remove();             removed = true;         }     }     return removed; }

三、超级实现类 AbstractCollection

通过以上的学习,我们可以知道在collection接口中,有很多通用的方法,根据现有的定义以及继承的Iterable接口,都可以在抽象方法中实现,这样就可以减少具体实现类需要实现的方法,所以就有了这么一个类–AbstractCollection。

首先我们来看看api文档对这个类的大概描述:

如果要实现一个不可修改的集合,只需要重写Iterator和size接口就可以了,并且返回的Iterator需要实现hasNext和Next。而要实现一个可以修改的集合,还必须重写add方法,返回的Iterator还要实现remove接口。

接下里我们来看看其方法定义

//这个毫无疑问,是可以直接获取的 public boolean isEmpty() {     return size() == 0; } //这个方法因为Iterator的存在,可以进行一致性封装,这里需要注意的是对象的比较是通过equals方法,因为调用到了it.next()与it.hasNext(),这也是为什么文档注释会写实现集合类需要重写Iterator的这两个方法。 public boolean contains(Object o) {     Iterator<E> it = iterator();     if (o==null) {         while (it.hasNext())             if (it.next()==null)                 return true;     } else {         while (it.hasNext())             if (o.equals(it.next()))                 return true;     }     return false; } //和contains类似,也是通过Iterator实现的,但其会调用it.remove()方法,这也是为什么文档注释会写实现可以修改的集合类时需要重写Iterator的remove方法。 public boolean remove(Object o) {     //...省略,这里调用了it.remove()方法 }

还有很多方法也用到了iterator的特性,例如containAll、addAll等等,这里就不一 一说明了。

除此之外,还有一个toArray方法,方法实现还有一些略微不同:

//这个实现相对复杂一些,可以看到扩容最主要的手段是Arrays.copyOf()方法, //也就是需要将原数组通过复制到新的数组中来实现的。 //注意这里返回的顺序和Iterator顺序一致 //在这里实现是为了方便不同具体实现类互相转换,我们在后续会多次见到此方法 public Object[] toArray() {     //先根据当前集合大小声明一个数组     Object[] r = new Object[size()];     Iterator<E> it = iterator();     for (int i = 0; i < r.length; i++) {         //集合元素没那么多,说明不需要那么大的数组         if (! it.hasNext())              return Arrays.copyOf(r, i); //仅返回赋完值的部分         r[i] = it.next();     }     //元素比从size()中获取的更多,就需要进一步调整数组大小     return it.hasNext() ? finishToArray(r, it) : r; } private static <T> T[] finishToArray(T[] r, Iterator<?> it) {     //记录当前大小     int i = r.length;     while (it.hasNext()) {         int cap = r.length;         //r的长度不够,继续分配         if (i == cap) {             //扩充方式为cap+cap/2+1,也就是1.5倍扩容             int newCap = cap + (cap >> 1) + 1;             // 超过了最大容量,MAX_ARRAY_SIZE=Integer.MAX_VALUE-8             if (newCap - MAX_ARRAY_SIZE > 0)                 //重新设置cap的值                 newCap = hugeCapacity(cap + 1);                          //对r进行扩容             r = Arrays.copyOf(r, newCap);         }         //赋值,进入下一轮循环         r[i++] = (T)it.next();     }     // 由于之前扩容是1.5倍进行的,最后再将其设置到和r实际需要的相同     return (i == r.length) ? r : Arrays.copyOf(r, i); } private static int hugeCapacity(int minCapacity) {     if (minCapacity < 0) // 超过了最大正整数,也就是负数         throw new OutOfMemoryError             ("Required array size too large");     return (minCapacity > MAX_ARRAY_SIZE) ?         Integer.MAX_VALUE :         MAX_ARRAY_SIZE; } //和toArray()方法类似,就不再赘述,具体可以查看源码 public <T> T[] toArray(T[] a) {     //... }

除了这些,我们再来看看AbstractCollection是怎么实现toString方法的吧+

其是通过StringBuilder拼接了每个元素的toString完成的,不是很复杂。

我们来看看源码吧

public String toString() {     Iterator<E> it = iterator();     if (! it.hasNext())         return "[]";     StringBuilder sb = new StringBuilder();     sb.append('[');     for (;;) {         E e = it.next();         sb.append(e == this ? "(this Collection)" : e);         if (! it.hasNext())             return sb.append(']').toString();         sb.append(',').append(' ');     } }

java基本数据类型有哪些

Java的基本数据类型分为:1、整数类型,用来表示整数的数据类型。2、浮点类型,用来表示小数的数据类型。3、字符类型,字符类型的关键字是“char”。4、布尔类型,是表示逻辑值的基本数据类型。

以上是“Java源码解析之接口Collection的示例分析”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注亿速云行业资讯频道!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI