十五、Java基础---------集合框架体系以及List
在介绍集合之前先说一下数组,正如我们所知,数组是某一类型数据的集合,强调的是数据,而且必须单一;集合框架的不同之处在于存储的数据类型没有任何限制,既可以存储基本数据类型(会自动提升为相应的包装类)也可以存储引用数据类型比如对象,集合框架更强大之处在于可以同时存储任意类型数据,这是数据无法做到的,另一方面,数组长度是固定的,但是实际生活中需求的容器大都是不确定的,这就需要一个可变长度的容器,而集合框架刚好弥补了数组容量固定的缺陷,这也是集合框架另一个特点;另一个不同之处就是存储方式的区别,数组数据结构是数组,在内存中是一个连续的区域,而集合框架则是分散存储(不同的类型不太一样,比如类似于数组结构的ArrayList、链表结构的LinkedList、红黑树结构的TreeSet等等)。
强调一下学习继承或者实现关系对象的学习方法:查看父类的功能,建立子类对象,查看父类功能原因在于,父类是子类共性的抽取,所以父类基本上涵括了子类的重要方法,建立子类对象的原因在于,有可能父类无法创建对象比如抽象类与接口,令一个原因在于子类的功能要大于父类的功能,所以使用起来更加的方便。
Collection体系
Collection
——| List 子接口,特点在于元素有序,可以重复
——| Vector:底层的数据结构是数组,线程安全,但速度慢,已被ArrayList替代。
——| ArrayList:底层的数据结构是数组。特点:查询速度很快。但是增删稍慢。线程不同步。
——| LinkedList:底层使用的链表数据结构。特点:增删速度很快,查询稍慢。线程不同步。
——| Set 子接口,特点在于元素无序,元素不可重复
——| HashSet:底层数据结构是哈希表,是线程不安全的,不同步。
——| TreeSet:可以对Set集合中的元素进行排序(红黑树)
Collection共性方法:
1.添加
boolean add(Object obj):添加单个元素
boolean addAll(Collection c):添加多个元素
2.删除
void clear():移除所有元素
boolean remove(Object o):移除单个元素,有一个删除,就返回true
boolean removeAll(Collection c):移除多个元素
3.判断
boolean contains(Object obj):判断元素是否存在
boolean containsAll(Collection c):判断一个集合的元素是否包含在当前集合中
boolean isEmpty():判断集合是否为空
4.获取
Iterator iterator():返回集合上的一个迭代器
int size():元素个数
5.获取交集
boolean retainAll(Collection c):交集
6.集合变数组
Object[] toArray()
特殊说明:
迭代器Iterator
迭代器的实现依赖于内部类,正如我们所知,人体包括心肝脾肾肺,这这些都是人体内部的独立单元,但是又无法脱离人体,所以在在描述人体时将心肝脾肾肺定义为人体的内部类。在操作集合框架元素时具体怎样去操作不同的数据结构有不同的实现,而这些不同的实现又依赖于集合框架,所以将迭代器定义为集合框架的内部类,从而可以通过集合对象直接访问集合中的元素。
迭代器的方法:
boolean hasNext()判断是否还有元素可以迭代
next()返回迭代的下一个元素,获取的元素默认为Object类
注意:
1.迭代器在Collcection接口中是通用的,它替代了Vector类中的Enumeration(枚举)
2.迭代器的next()方法是自动向下取元素,要避免出现NoSuchElementException
3.迭代器的next方法返回值类型是Object,所以要记得类型转换
List接口特有功能:
1.添加元素
void add(int index, Object element):在指定位置添加指定元素
boolean addAll(index i,Collection<? extends E> c)
2.删除元素
Object remove(int index):返回并删除指定位置的元素
3.修改元素
Object set(int index, Object element):修改指定位置的元素
4.查找元素
Object get(int index):根据指定索引获取元素
List<E> subList(int fromIndex, int toIndex)返回列表中指定的fromIndex(包括)和toIndex(不包括)之间的部分视图。
int indexOf(Object o)返回此列表中第一次出现的指定元素的索引,如不包括,返回-1
ListIterator listIterator()List特有的迭代器
List特有迭代器
ListIterator<E> listIterator():返回按适当顺序在列表的元素上进行迭代的迭代器。
List迭代器特有方法:
void add(E e) 将指定的元素插入列表
boolean hasPrevious() 如果以逆向遍历列表,列表迭代器有多个元素,则返回 true
int nextIndex() 返回对 next 的后续调用所返回元素的索引
E previous() 返回列表中的前一个元素
int previousIndex() 返回对 previous 的后续调用所返回元素的索引
void set(E e) 用指定元素替换 next 或 previous 返回的最后一个元素
void remove()从列表中移除由 next 或 previous 返回的最后一个元素
ListIterator说明:
在迭代器时,只能用迭代器的方法操作元素,可是Iterator方法是有限的,只能对元素进行判断,取出,删除的操作,如果想要其他的操作如添加,修改等,就需要使用List特有迭代器:ListIterator。
如果使用公用迭代器,在修改迭代元素是会发生 ConcurrentModificationException 异常
Vector
说明:底层的数据结构是数组,线程同步,效率低已被ArrayList替代
特点:查询快,增删慢
Vector特有方法:
1.添加元素
void addElement(Object obj) JDK1.2 后改为了add(Object obj)
2.获取元素
Object elementAt(int index) JDK1.2后就改为了get(int index),通过角标拿元素
3.遍历元素
Enumeration elements()
boolean hasMoreElements()
Object nextElement()
Enumeration elements()
Enumeration就是枚举,枚举就是Vector特有的取出方式。
Arraylist
说明:底层的数据结构使用的是数组结构。
特点:查询速度很快。但是增删稍慢。线程不同步。
LinkList
说明:底层使用的链表数据结构。
特点:增删速度很快,查询稍慢,线程不同步。
LinkList特有方法:
1.添加元素:
void addFirst(E e) 将指定元素插入此列表的开头。
void addLast(E e) 将指定元素添加到此列表的结尾。
2.获取元素:
E getFirst()返回此列表的第一个元素。
E getLast()返回此列表的最后一个元素。
3.删除元素:
E removeFirst()移除并返回此列表的第一个元素。
E removeLast()移除并返回此列表的最后一个元素。
事例演示:
1.向vector中方添加元素,并使用特有方法遍历Vector
import java.util.Enumeration; import java.util.Vector; class VectorDemo { public static void main(String[] args) { Vector v = new Vector(); v.add("java01");//使用Collection共有方法向Vector中添加元素 v.add("java02"); v.add("java03"); v.addElement("java04");//使用Vector特有方法向Vector中添加元素 Enumeration en = v.elements();//使用Vector特有方法迭代元素 while(en.hasMoreElements()) { System.out.println(en.nextElement()); } } }
2. 向ArrayList中添加Person对象,去重,并用特有方法遍历ArrayList(特有方法可以在遍历的同时进行修改,本例子省略)
package List; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.ListIterator; /* 将自定义对象作为元素存到ArrayList集合中,并去除重复元素。 比如:存人对象。同姓名同年龄,视为同一个人。为重复元素。 思路:对人进行描述,将数据封装进对象 定义容器,将数据存入,取出。 */ class Person{ public String name; public int age; Person(String name,int age){ this.name=name; this.age=age; } public String getName(){ return name; } public int getAge(){ return age; } //重写equals方法,规定name,age相同则表示同一个对象 public boolean equals(Object o) { if(!(o instanceof Person)) return false; Person p=(Person) o; return this.name.equals(p.name)&&this.age==p.age; } } public class ArrayListDemo1 { public static void main(String[] args) { List l=new ArrayList(); l.add(new Person("01",20));//使用公用方法向ArrayList中添加Person对象。 l.add(new Person("02",30)); l.add(new Person("02",30)); l.add(new Person("04",50)); l.add(new Person("04",50)); print(l);//打印去重之前的ArrayList l=signleElement(l);//去重 System.out.println(l.remove(new Person("01",20)));//只匹配第一个相同的对象,也就是只删除第一个匹配的元素 print(l);//打印去重之后的ArrayList } //去重,并返回ArrayList public static ArrayList signleElement(List l){ ArrayList newList=new ArrayList(); Iterator it=l.iterator(); while(it.hasNext()) { Object o=it.next(); if(!newList.contains(o)) newList.add(o); } return newList; } //打印 static void print(List list) { ListIterator it=list.listIterator();//特有方法遍历,可以修改元素值,本例子省略 while(it.hasNext()) { Person p=(Person) it.next(); System.out.println(p.getName()+"...."+p.getAge()); } } }
3.使用LinkedList模拟队列的FIFO规则
package List; /* 使用LinkedList模拟一个堆栈或者队列数据结构。 堆栈:先进后出 如同一个杯子。 队列:先进先出 First in First out FIFO 如同一个水管。 */ import java.util.*; class DuiLie { private LinkedList link; DuiLie() { link = new LinkedList(); } public void myAdd(Object obj) { link.addFirst(obj);//在第一个元素位置添加元素 } public Object myGet()//获取第一个元素,从而模拟队列的FIFO { return link.removeFirst(); } public boolean isNull() { return link.isEmpty(); } } public class LinkedListDeno { public static void main(String[] args) { DuiLie dl = new DuiLie(); dl.myAdd("java01"); dl.myAdd("java02"); dl.myAdd("java03"); dl.myAdd("java04"); while(!dl.isNull()) { System.out.println(dl.myGet()); } } }