黑马程序员——Java集合框架—概述
来源:互联网 发布:内衣品牌推荐 知乎 编辑:程序博客网 时间:2024/06/08 04:22
1、Java集合框架类结构图
下面是java集合框架的类结构图(包括接口、抽象类、遗留构件,不包括Queue的实现,图片来自网络):
上面的图可能比较复杂,下面再贴2张简化图(图片来自网络):
从上面的图片中可以看出,java的集合类主要由2个接口派生而出:Collection和Map,这2个接口是java集合框架的根接口。
本文仅仅简单介绍一下Collection接口,关于Map接口将在以后的文章中介绍。
2、Collection接口简要分析
从上面的类结构图可以看出,Collection接口是Set、Queue、List的父接口,所以在Collection接口中定义的是3个子接口共有的方法。
List和Set、Queue很大的一个不同点是,List是有索引的,它可以通过索引来获取对象(即获取对象时需要传一个index参数),但是另外2个集合没有索引(获取对象时传入一个对象),所以在Collection接口中没有定义获取集合中元素的方法。
3个集合添加元素的方式是相同的,都需要传入被添加的对象,所以在Collection接口中定义了添加元素的方法。
下面看一下Collection接口的源码:
package java.util;public interface Collection<E> extends Iterable<E> {//返回集合里元素的个数 int size();//返回集合是否为空。当集合长度为0时返回true,否则返回false。 boolean isEmpty();//返回集合里是否包含指定元素 boolean contains(Object o);//返回一个Iterator对象,用于迭代集合里的元素 Iterator<E> iterator();//把集合变成一个数组并返回 Object[] toArray();// <T> T[] toArray(T[] a);//向集合里添加一个元素,如果集合对象被该添加操作改变了,则返回true。 boolean add(E e);//删除集合中的指定元素,当集合中包含一个或多个指定元素时,这些元素都会被删除。如果成功删除返回true,否则返回false。 boolean remove(Object o);//返回当前集合中是否包含指定集合c中的所有元素 boolean containsAll(Collection<?> c);//把集合c里的所有元素添加到当前集合中 boolean addAll(Collection<? extends E> c);//把指定集合c中包含的元素从当前集合中删除 boolean removeAll(Collection<?> c);//将当前集合的内容变成当前集合与指定集合c的交集 boolean retainAll(Collection<?> c);//清除集合里的所有元素,将集合长度变为0。 void clear(); boolean equals(Object o); int hashCode();}
从源码可以看出Collection是一个接口,并且继承了Iterable接口。iterable可以翻译为可迭代,可以理解为凡是实现了Itreable接口的类都是可以迭代的。
下面看一下Iterable接口的源码:
package java.lang;import java.util.Iterator;public interface Iterable<T> { Iterator<T> iterator();}
从上面的源码可以看出,Iteable接口中只有一个方法,该方法返回一个迭代器Iterator的实例。
下面看一下Iterator接口的源码:
package java.util;public interface Iterator<E> {//被迭代的集合中是否还有下一个元素 boolean hasNext();//返回下一个元素 E next();//删除集合即上一次next方法返回的元素 void remove();}
从上面的源码可以看出,Iterator实际上也是一个接口。因为接口是不能创建实例的,所以Iterable的iterator方法返回的肯定是Iterator接口子类的实例。
那Iterable的子类是在哪里定义的呢??
下面我们以ArrayList为例稍微说一下Iterable接口的子类。
我们可以从ArrayList类的源代码中看到如下代码:
package java.util;public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable{//这是从Collection接口继承得到的iterator方法public Iterator<E> iterator() {//下面的代码返回了一个Itr类的实例 return new Itr(); } //私有内部类Itr,实现了Iterable接口 private class Itr implements Iterator<E> { int cursor; // index of next element to return int lastRet = -1; // index of last element returned; -1 if no such int expectedModCount = modCount; public boolean hasNext() { return cursor != size; } @SuppressWarnings("unchecked") public E next() { checkForComodification(); int i = cursor; if (i >= size) throw new NoSuchElementException(); Object[] elementData = ArrayList.this.elementData; if (i >= elementData.length) throw new ConcurrentModificationException(); cursor = i + 1; return (E) elementData[lastRet = i]; } public void remove() { if (lastRet < 0) throw new IllegalStateException(); checkForComodification(); try { ArrayList.this.remove(lastRet); cursor = lastRet; lastRet = -1; expectedModCount = modCount; } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } } final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); } }}
从上面代码可以看出,ArrayList的iterator方法返回的是一个内部类Itr的实例,该内部类实现了Iterator接口。
不仅仅是ArrayList,你可以从其他的集合类中找到类似的代码。
最后看一个使用Iterator的小例子,及几个需要注意的点:
package org.lgy.study.collection;import java.util.Collection;import java.util.ArrayList;import java.util.Iterator;public class IteratorTest{public static void main(String[] args){Collection c = new ArrayList();/*代码片段1:Iterator对象的next方法返回的是集合对象中元素的值。如果集合中的元素为基本数据类型,则返回基本数据类型对应的值;如果是引用类型,则返回对应的引用(也可以理解为元素指向的地址),此时如果通过获得的引用变量修改了所引用的对象,则导致集合元素也被修改。*/c.add(new Name("Ying", "Tony"));System.out.println(c);Iterator iterator = c.iterator();while(iterator.hasNext()){Name name = (Name)iterator.next();name.setFirstName("li");name.setLastName("guoying");}System.out.println(c + "\n");/*代码片段2:当使用Iterator迭代集合时,不能在迭代语句内部使用集合本身的方法删除、添加集合元素,否则引发ConcurrentModificationException异常。(可以修改元素,不抛出异常,但不建议直接修改)如果需要在迭代的过程中删除元素,应该使用Iterator的remove方法。*/c.clear();c.add("111");c.add("222");c.add("333");Iterator iterator2 = c.iterator();while(iterator2.hasNext()){Object obj = iterator2.next();System.out.print(obj + " ");//下面代码是在添加集合元素时引发异常。//无论在哪里添加新元素,都会引发异常。if(obj.equals("333"))c.add(0.5);/*//下面代码是在删除集合元素时引发异常。//当删除111、333时会引发异常,在删除222时不会引发异常,但依然不建议在//迭代元素的同时使用集合本身的方法删除集合元素。if(obj.equals("222"))c.remove(obj);*/}/*下面代码使用for each迭代集合*/c.clear();c.add("111");c.add("222");c.add("333");for(Object obj : c){System.out.print(obj + " ");}System.out.println();/*迭代集合时,for each 返回的是集合元素的值*/c.clear();c.add(new Name("li", "guoying"));for(Object obj : c){Name name = (Name)obj;System.out.print(name);name.setFirstName("Tony");name.setLastName("Ying");}System.out.println("\n" + c);/*迭代集合的过程中,不能删除、添加元素,否则引发ConcurrentModifactionException异常具体请参见使用Iterator迭代时的情况*/c.add("111");c.add("222");c.add("333");for(Object obj : c){System.out.print(obj + " ");if(obj.equals("333"))c.remove(obj);}}}class Name{private String firstName;private String lastName;public Name(String firstName, String lastName){this.firstName = firstName;this.lastName = lastName;}public void setFirstName(String firstName){this.firstName = firstName;}public void setLastName(String lastName){this.lastName = lastName;}public String toString(){return firstName + lastName;}}
3、AbstraceCollection抽象类简要分析
Collection是一个接口,它有一个名为AbstractCollection的实现类(抽象类)。下面我们看一下AbstractCollection的源码:
package java.util;public abstract class AbstractCollection<E> implements Collection<E> { protected AbstractCollection() { }//抽象方法,没有实现 public abstract Iterator<E> iterator();//抽象方法,没有实现 public abstract int size(); public boolean isEmpty() { //已实现 } public boolean contains(Object o) { //已实现 } public Object[] toArray() { //已实现 } public <T> T[] toArray(T[] a) { //已实现 } public boolean add(E e) { //已实现 } public boolean remove(Object o) { //已实现 } public boolean containsAll(Collection<?> c) { //已实现 } public boolean addAll(Collection<? extends E> c) { //已实现 } public boolean removeAll(Collection<?> c) { //已实现 } public boolean retainAll(Collection<?> c) { //已实现 } public void clear() { //已实现 }//重写Object中的toString方法 public String toString() { //已实现 }//equals和hashCode方法由Object类实现了//boolean equals(Object o); //int hashCode();}
从源码可以看出,AbstractCollection抽象类中只有2个抽象方法(iterator、size),2个方法(toString、hashCode)由Object类实现,其余11个从Collection接口继承的方法全部提供了实现。
集合类和数组不一样,数组元素既可以是基本类型的值,也可以是对象(实际上保存的是对象的引用),而集合里只能保存对象(实际上保存的是对象的引用),甚至可以在一个集合中保存不同类型的对象。
关于List、 Set、Map等后面会分类介绍。
- 黑马程序员——Java集合框架—概述
- 黑马程序员——集合框架概述
- 黑马程序员——集合框架Collection概述
- 黑马程序员——Java集合框架
- 黑马程序员——Java集合框架
- 黑马程序员——java集合框架
- 黑马程序员——java-集合框架
- 黑马程序员——JAVA集合框架
- 黑马程序员——java集合框架
- 黑马程序员——Java集合框架
- 黑马程序员——Java集合框架
- 黑马程序员—java集合框架应用
- 黑马程序员—java集合框架
- 黑马程序员—Java集合框架(LinkedList)
- 黑马程序员—java集合框架整理
- 黑马程序员—Java集合框架
- 黑马程序员:Java基础——集合框架之体系概述、共性方法与迭代器
- 黑马程序员—java技术blog—第七篇集合整体基础框架概述
- HDU 3917 Road constructions(最小割---最大权闭合)
- poj 1721 CARDS (置换群)
- conversion to dalvik format failed with error 1
- Spring中@component注解
- [寒江孤叶丶的Cocos2d-x之旅_12]浅谈Cocos2d-x中的内置粒子效果,和粒子的plist的导入
- 黑马程序员——Java集合框架—概述
- 【iOS】UICollectionView自定义Layout之蜂窝布局
- 引导加载程序之争:了解 LILO 和 GRUB
- poj上 G++ GCC C++编译器的区别?
- 设计模式--桥接模式
- MapReduce(十八): MR任务开发说明
- 进程——《现代操作系统》学习笔记
- java学习笔记11
- HDU--1247:Hat’s Words (字典树)