本文共 10744 字,大约阅读时间需要 35 分钟。
Collection:单列集合,该接口有两个重要的子接口List Set,他们的实现子类都是单列集合
Map:双列集合,Map接口的实现子类,存放K-Vpublic interface Collection< E > extends Iterable < E >
1 ) collection实现子类可以存放多个元素, 每个元素可以是Object
2)有些Collection的实现类,可以存放重复的元素,有些不可以
3)有些Collection的实现类,有些是有序的(List), 有些不是有序(Set)
4) Collection接口没有直接的实现子类,是通过它的子接口Set和List来实现的1) add:添加单个元素2) remove:删除指定元素3) contains:查找元素是否存在4) size:获取元素个数5) isEmpty:判断是否为空6) clear:清空7) addAll:添加多个元素8) containsAll:查找多个元素是否都存在9) removeAll:删除多个元素
public class CollectionMethod { public static void main(String[] args) { List list=new ArrayList();// 1) add:添加单个元素 list.add("zlj"); list.add(10); list.add(true);// 2) remove:删除指定元素 list.remove(1); System.out.println("list:"+list);// 3) contains:查找元素是否存在 System.out.println(list.contains(true));// 4) size:获取元素个数 System.out.println(list.size());// 5) isEmpty:判断是否为空 System.out.println(list.isEmpty());// 6) clear:清空 list.clear(); System.out.println("list:"+list);// 7) addAll:添加多个元素 ArrayList list2=new ArrayList(); list2.add("西游记"); list2.add("水浒传"); list.addAll(list2);// 8) containsAll:查找多个元素是否都存在 list.containsAll(list2);// 9) removeAll:删除多个元素 list.add("java虚拟机"); list.removeAll(list2); System.out.println("list:"+list); } }
Iterator对象称为迭代器,主要用于遍历Collection集合中的元素。2)所有实现了Collection接口的集合类都有一个iterator(0方法, 用以返回一个实现了Iterator接口的对象, 即可以返回一个迭代器。
Iterator的结构
注意:在调用iterator.next()方法之前必须要调用iterator.hasNext()进行检测。若不调用,且下一条记录无效,直接调用iterator.next()会抛出NoSuchElementException异常。如果希望再次遍历,需要我们重置一个迭代器Iterator仅用于遍历集合, Iterator本身并不存放对象。
实例演示
public class CollectionIterator { public static void main(String[] args) { List list=new ArrayList(); list.add(new Book("java虚拟机","300")); list.add(new Book("java规范","100")); list.add(new Book("Spring","200")); //1:先得到list对于的迭代器 Iterator iterator = list.iterator(); //2:使用while循环遍历,判断是否还有数据 while (iterator.hasNext()){ //3:返回下一个元素 System.out.println(iterator.next()); } }}class Book{ private String name; private String price; @Override public String toString() { return "Book{" + "name='" + name + '\'' + ", price='" + price + '\'' + '}'; } public Book(String name, String price) { this.name = name; this.price = price; }}
增强for循环(底层仍然是iterator迭代器),可以代替iterator迭代器,特点:增强for就是简化版的iterator,本质一样。只能用于遍历集合或数组。for循环增强也可以在数组中使用
基本语法
for(元素类型元素名:集合名或数组名){ 访问元素 }
实例演示:如上代码的iterator改成for循环增强即可
//.. for (Object book:list){ System.out.println("book="+book); } //...
book=Book{name='java虚拟机', price='300'}book=Book{name='java规范', price='100'}book=Book{name='Spring', price='200'}
List接口是Collection接口的子接口
List集合类中元素有序(即添加顺序和取出顺序一致)、 且可重复,
List集合中的每个元素都有其对应的顺序索引,即支持索引。
List容器中的元素都对应一 个整数型的序号记载其在容器中的位置, 可以根据序号存取容器中的元素。
案例演示public class ListMethod { public static void main(String[] args) { // List集合类中元素有序(即添加顺序和取出顺序一致)、 且可重复, List list=new ArrayList(); list.add(1); list.add(2); list.add(3); list.add(3); System.out.println("list="+list);//List集合中的每个元素都有其对应的顺序索引,即支持索引。 System.out.println(list.get(3)); }}
list=[1, 2, 3, 3]3
List集合里添加了一些根据索引来操作集合元素的方法
void add(int index, Object ele):在index位置插入ele元素
boolean addAll(int index, Collection eles):从index位置开始将eles中的所有元素添加进来
Object get(int index):获取指定index位置的元素
int indexOf(Object obj):返回obj在集合中首次出现的位置
int lastIndexOf(Object obj):返回obj在当前集合中末次出现的位置
Object remove(int index):移除指定index位置的元素,并返回此元素
Object set(int index, Object ele):设置指定index位置的元素为ele ,相当于是替换.
List subList(int fromIndex, int tolndex):返回从fromIndex到tolndex位置的子集合
案例演示public class ListMethod { public static void main(String[] args) { // List集合类中元素有序(即添加顺序和取出顺序一致)、 且可重复, List list=new ArrayList(); list.add(1); list.add(2); list.add(3); list.add(3); System.out.println("list="+list);//List集合中的每个元素都有其对应的顺序索引,即支持索引。 System.out.println(list.get(3));// 1) void add(int index, Object ele):在index位置插入ele元素 list.add(1,"java"); System.out.println("list="+list);// 2) boolean addAll(int index, Collection eles):从index位置开始将eles中的所有元素添加进来 List list2= new ArrayList(); list2.add("男"); list2.add("女"); list.addAll(1,list2); System.out.println("list="+list);// 3) Object get(int index):获取指定index位置的元素 System.out.println( list.get(1));//// 4) int indexOf(Object obj):返回obj在集合中首次出现的位置 System.out.println(list.indexOf(3));// 5) int lastIndexOf(Object obj):返回obj在当前集合中末次出现的位置 System.out.println(list.lastIndexOf(3));// 6) Object remove(int index):移除指定index位置的元素,并返回此元素 list.remove(0); System.out.println("list="+list);// 7) Object set(int index, Object ele):设置指定index位置的元素为ele ,相当于是替换. list.set(0,"man"); System.out.println("list="+list);// 8) List subList(int fromIndex, int tolndex):返回从fromIndex到tolndex位置的子集合 System.out.println(list.subList(0,3)); }}
public class ListFor { public static void main(String[] args) { List list=new ArrayList(); list.add(1); list.add(2); list.add(3); list.add(3); //1.迭代器 System.out.println("======迭代器======="); Iterator iterator = list.iterator(); while (iterator.hasNext()) { Object next = iterator.next(); System.out.println(next); } System.out.println("======增强for循环======="); for (Object object:list){ System.out.println(object); } System.out.println("======普通for循环======="); for (int i=0;i
ArrayList的注意事项
ArrayList可以加入null,并且加多个
ArrayList是由数组来实现数据存储的
ArrayList基本等同于Vector ,除了ArrayList是线程不安全(执行效率高)看源码,在多线程情况下,不建议使用ArrayList
ArrayList的底层操作机制源码分析(重点,难点)
先说结论在分析源码 1 ) ArrayList中维护了一个Object类型的数组elementDatatransient Object[] elementData//transient 表示短暂的,瞬间,表示该属性不会被序列化
2)当创建对象时,如果使用的是无参构造器,则初始elementData容量为0 (jdk7是10)
3)当添加元素时:先判断是否需要扩容,如果需要扩容,则调用grow方法,否则直接添加元素到合适位置4)如果使用的是无参构造器,如果第一次添加,需要扩容的话,则扩容elementData为10,如果需要再次扩容的话,则扩容elementData为1.5倍。
5)如果使用的是指定容量capacity的构造器,则初始elementData容量为capacity
6)如果使用的是指定容量capacity的构造器,如果需要扩容,则直接扩容elementData为1.5倍。
当创建对象时,如果使用的是无参构造器案例演示
public class ArrayListSource { public static void main(String[] args) { //解读源码 //使用无参构造器创建ArrayList对象 ArrayList arrayList=new ArrayList(); //使用for循环给list添加1-10数据 for (int i=0;i<=10;i++){ arrayList.add(i); } //使用for循环给list添加11-15数据 for (int i=11;i<=15;i++){ arrayList.add(i); } //使用for循环给list添加16,17,18数据 arrayList.add(100); arrayList.add(200); arrayList.add(null); }}
源码剖析
Debug 当创建对象时,如果使用的是有参构造器案例演示 源码剖析 DebugVector注意事项
1)Vector类的定义说明 2) Vector底层也是一个对象数组protected Object[] elementData;
3 ) Vector是线程同步的,即线程安全,Vector类的操作方法带有synchronized
public synchronized E get(int index) { if (index >= elementCount) throw new ArrayIndexOutOfBoundsException(index); return elementData(index); }
4)在开发中需要线程同步安全时,需要考虑使用Vector
案例演示public class VectorSource { public static void main(String[] args) { //无参构造器 Vector
源码剖析
Debug全面说明
1 ) LinkedList底层实现了双向链表和双端队列特点 2 )可以添加任意元素(元素可以重复),包括null 3 )线程不安全,没有实现同步LinkedList的底层操作机制
1 ) LinkedList底层维护了一个双向链表.
2 ) LinkedList中维护了两个属性first和last分别指向首节点和尾节点
3)每个节点(Node对象) ,里面又维护了prev、next、 item三个属性,其中通过prev指向前一个,通过next指向后一个节点。最终实现双向链表.
4)所以LinkedList的元素的添加和删除,不是通过数组完成的,相对来说效率较高。
模拟双向链表遍历public class LinkedListDemo { public static void main(String[] args) { //模拟一个简单的双向链表 Node zlj = new Node("zlj"); Node zzg = new Node("zzg"); Node lqx = new Node("lqx"); //连接三个节点,形成双向链表 //zlj->zzg->lqx zlj.next=zzg; zzg.next=lqx; //lqx->zzg->zlj lqx.pre=zzg; zzg.pre=zlj; Node first=zlj;//first引用指向zlj,就是双向链表的头节点 Node last=lqx;//last引用指向lqx,就是双向链表的尾节点 //从头到尾进行遍历 System.out.println("============从头到尾进行遍历============"); while (true){ if (first==null) { break; } System.out.println(first); first=first.next; } //从尾到头进行遍历 System.out.println("============从尾到头进行遍历=============="); while (true){ if (last==null){ break; } System.out.println(last); last=last.pre; } }}//定义一个Node类,Node对象,表示双向链表的一个节点class Node{ public Object item;//真正存放数据 public Node next;//指向后一个节点 public Node pre;//指向前一个结点 public Node(Object name){ this.item=name; } @Override public String toString() { return "Node{" + "item=" + item + '}'; }}
============从头到尾进行遍历============Node{item=zlj}Node{item=zzg}Node{item=lqx}============从尾到头进行遍历==============Node{item=lqx}Node{item=zzg}Node{item=zlj}
模拟双向链表的添加和删除(主要代码和上面一样)
//.... //演示链表添加对象 Node node = new Node("添加元素"); zlj.next=node; node.next=zzg; zzg.pre=node; node.pre=zlj; //..
============从头到尾进行遍历============Node{item=zlj}Node{item=添加元素}Node{item=zzg}Node{item=lqx}
/... //演示链表添加对象 Node node = new Node("添加元素"); zlj.next=node; node.next=zzg; zzg.pre=node; node.pre=zlj; //演示链表删除对象 zlj.next=zzg; zzg.pre=zlj; //..
============从头到尾进行遍历============Node{item=zlj}Node{item=zzg}Node{item=lqx}
linkedList 的add方法源码剖析
public class LinkedListCRUDSource { public static void main(String[] args) { LinkedList linkedList = new LinkedList(); linkedList.add(1); linkedList.add(2); System.out.println("linkedList="+linkedList); }}
1)如果我们改查的操作多,选择ArrayList
2)如果我们增删的操作多,选择LinkedList
3)一般来说,在程序中,80%-90%都是查询,因此大部分情况下会选择ArrayList
4)在一个项目中,根据业务灵活选择,也可能这样,一个模块使用的是ArrayList,另外一个模块是LinkedList.转载地址:http://srozi.baihongyu.com/