一、集合框架概述
集合类(集合框架)
对象多了用集合存,数据多了用对象存。
为什么出现集合类?
面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,就对对象进行存储,集合就是存储对象最常用的一种方式。
数组和集合类同是容器,有何不同?
数组虽然也可以存储对象,但长度是固定的;集合长度是可变的。数组中可以存储基本数据类型,集合只能存储对象。
集合类的特点
集合只用于存储对象,集合长度是可变的,集合可以存储不同类型的对象。
为什么会出现这么多的容器呢?
因为每一个容器对数据的存储方式都有不同。这个存储方式称之为:数据结构。
集合框架体系结构:参阅顶层(可能抽象)创建立底层(方法多)集合框架的体系结构
二、Collection体系结构
Collection层次是一个根接口,是集合框架体系的最顶层。此接口是Java Collections Framework的一个成员。他无构造方法只有抽象方法。
Collection有两个常见的子接口:List和Set。
List接口中有三个子类:ArrayList、LinkedList、Vector。
Set接口中有两个子类:HashSet、TreeSet。
为什么会出现这么多的容器呢?
因为每一个容器对数据的存储方式都有不同,这个存储方式称为数据结构。
注:1、集合中存的不是对象实体,里面存的是对象的引用(内存地址)。
2、add()方法的参数类型是object,以便于接收任意类型对象 。三、Collection中常用的共性方法:
1、增加
add(E e) 增加一个元素
addAll(Collection<? extends E> c) 添加一组元素,参数为一个容器
2、删除
clear() 移除此collection中的所有元素。清空容器。
remove(Object o) 从此collection中移除指定元素。
removeAll(Collection<?> c) 移除此collection中那些也包含在指定collection中的所有元素
3、取出
Iterator<E> iterator() 返回在此collection的元素上进行迭代的迭代器。
4、判断
contains(Object o ) 如果此collection包含指定元素,则返回true。
containsAll(Collection<?> c) 判断是否包含一堆元素。指定容器中的全部元素。
isEmpty() 判断集合中是否有元素
size() 获取容器的长度
retainAll(Collection<?> c) 仅保留collection中那些也包含在指定collection的元素。
toArray() 返回包含此collection中的所有元素的数组。
<T> T[] toArray(T[] a) 返回包含此collection中所有元素的数组。collection共性方法示例:
importjava.util.*;
classCollectionDemo
{
public static void main(String[] args)
{
method_2();
}
public static void method_get() // 获取元素方法演示
{
ArrarList al1 = newArrayList();
al1.add(“java01”);
al1.add(“java02”);
al1.add(“java03”);
al1.add(“java04”);
}
public static void method_2() // retain()方法演示和removeAll()方法演示
{
ArrarList a1 = new ArrayList();
a1.add(“java01”);
a1.add(“java02”);
a1.add(“java03”);
a1.add(“java04”);
ArrarList a2 = newArrayList();
a2.add(“java01”);
a2.add(“java02”);
a2.add(“java05”);
a2.add(“java06”);
// 取交集,a1中只会保留和a2中相同的元素
a1.retainAll(a2);
sop(“a1:”+a1);
sop(“a2:”+a2);
// a1中只会保留a2中没有的元素
a1.removeAll(a2);
}
public static void base_method() // 添加删除判断获取长度等方法演示
{
// 创建一个集合容器,使用Collection接口的子类。ArrayList
ArrarList a1 = newArrayList();
// 1、添加元素
a1.add(“java01”);
a1.add(“java02”);
a1.add(“java03”);
a1.add(“java04”);
// 打印原集合
sop(“原集合:”+a1); // 结果为[java01、java02、java03、java04]
// 3、删除
a1.remove(“java02”);
sop(a1); // 结果为[java01、java03、java04] 删除后的结果
// 4、判断元素
sop(“java03是否存在:”+a1.contains(“java03”));
sop(“数据是否为空?”+a1.isEmpty());
// 3、清空删除
a1.clear(); // 结果为[ ] 清空删除后的结果
// 2、获取个数,集合长度
sop(“size:”+a1.size());
}
public static void sop(String str) // 定义方法用于输出
{
System.out.println(str);
}
}
四、元素的取出——迭代器
Iterator接口:迭代器
什么是迭代器?
迭代器就是集合的取出元素的方式。与遍历道理相同。
说明:不同的存储方式有不同的数据结构,故取出方式不同(每个容器判断取出的方式依赖每个容器的内部结构所以就把取出方式定义在集合的内部,这样取出方式就可以直接访问集合内部的元素,那么取出方式就被定义成了内部类。而每一个容器的数据结构不同,所以取出的动作细节也不一样。但是都有共性内容判断和取出,那么可以将这些共性抽取,形成一个接口名为Iterator。那么这些内部类都符合一个规则,该规则是Iterator。如何获取集合的取出对象呢?通过一个对外提供的方法,iterator()),迭代器把取出的动作封装起来。通过这个用于取出的类被定义在集合的内部。
iterator()方法返回一个Iterator类型的接口。
Iterator接口中有三个方法:
hasNext:如果仍有元素,返回true。
next:返回迭代的下一个元素。
remove:从迭代器指向的collection中移除迭代器返回的最后一个元素。
classCollectionDemo
{
public static voidmain(String[] args) // 主函
{
method_get(); // 调用方法
}
public static voidmethod_get() // 定义自定义方法用于取出
{
ArrarList a1 = newArrayList(); // 定义一个集合容器a1
a1.add(“java01”); // 添加元素
a1.add(“java02”);
a1.add(“java03”);
a1.add(“java04”);
Iterator it = al.iterator(); // 接口迭代方法用于取出元素继承自ListIterator接口
sop(it.hasNext()); // 如果仍有元素可以迭代,则返回true。用于判断循环条件。
sop(it.next()); // 逐个向下获取元素
while(it.hasNext()) // 方法一:循环逐个输出元素
{
sop(it.next()); // 逐个向下获取元素
}
for(Iterator it =al.iterator();it.hasNext() ;) // 方法二:循环逐个输出元素,局部变量释放内存
{
sop(it.next()); // 逐个向下获取元素
}
}
public static void sop(Stringstr) // 定义方法用于输出
{
System.out.println(str);
}
}
五、List集合
Collection接口下有List和Set两个类都包含Collection中的(add、remove、cotains、clear、iterator)方法。
Collection
|--List:元素是有序的,元素可以重复。因为该集合体系有索引。
|--Set:元素无序,元素不可以重复。
List接口中有三个子类:ArrayList、LinkedList、Vector。
List中的特有方法有:(凡是可以操作角标的方法都是该体系的特有方法)
1、增
add(int index, element) 在指定索引处插入元素。
addAll(index,Collection) 在指定位置插入一堆元素。
2、删
remove(int index) 按照角标删除
remove(Object o) 按照元素删除
3、改
set(int index,E element) 用指定元素替换列表中指定位置的元素(List特有)。
4、查
get(int index) 根据位置获取元素。
subList(int fromIndex,int toIndex) 返回列表中指定的之间部分的视图,包含头,不包含尾。
listIterator() 返回此列表元素的列表迭代器(List的特有迭代器)。
indexOf(Object o) 返回元素在列表中第一次出现的位置,若不包含返回-1。
lastIndexOf(Object o) 返回元素在列表中第一次出现的位置,若不包含返回-1。
List集合特有的迭代器即列表迭代器ListIterator。列表迭代器可添加、判断、取出、删除、修改。
ListIterator是Iterator的子接口。
在迭代时不能通过集合对象的方法操作集合中的元素。会发生ConcurrentModificationException异常。所以在迭代器是只能用迭代器的方法操作元素,可数Iterator方法是有限的,只能对元素进行判断,取出,删除等操作,如果想要其他的操作如添加,修改等,就需要使用其子接口,ListIterator。该接口只能通过List集合的ListIterator方法获取。
ListIterator迭代器中的方法有:
add() 增加
hasNext() 正向遍历即判断迭代后面面有没有元素
hasPrevious() 逆向遍历即判断迭代前面有没有元素
next() 迭代器往后一个取值
nextIndex()
previous() 迭代器往前一个取值
previousIndex()
remove() 删除
set() 修改
List集合迭代器示例:并发访问会产生安全隐患,不能对同一组元素进行多种同时操作,集合和迭代器的操作不能一起运行。所以引入了ListIterator迭代器。
import java.util.*;
class ListDemo
{
public static void sop(Object obj)
{
System.out.println(obj);
}
public static void main(String[] args)
{
// 演示ListIterator列表迭代器
ArrayList al = newArrayList();
// 添加元素
al.add(“java01”);
al.add(“java02”);
al.add(“java03”);
// 在迭代过程中,准备添加或者删除元素。
Iterator it = al.iterator(); // 会出现异常,集合操作和迭代操作并发引起的错误
while(it.hasNext())
{
Object obj =it.next();
if(obj.equals(“java02”))
{
al.add(“java008”); // 集合操作
it.remove(); // 将java02的引用从集合中删除,但此时obj还在用所以可以输出
sop(“obj=”+obj);
}
}
// 在迭代过程中,准备添加或者删除元素。 此种方式可行列表迭代器的用途
ListIterator li =al.listIterator();
while(li.hasNext())
{
Object obj =li.next();
if(obj.equals(“java02”))
li.add(“java009”); // 添加位置在java02的后面。
else if(obj.equals(“java03”))
li.set(“java007”); // 将java03修改为java007
}
}
public static void method() // List方法演示
{
ArrayList al = newArrayList();
// 添加元素
al.add(“java01”);
al.add(“java02”);
al.add(“java03”);
sop(“原集合是:”+al); // 结果是:原集合是:[java01,java02,java03]
// 在指定位置添加元素。
al.add(1,”java09”); // 结果是: [java09,java01,java02,java03]
sop(al);
// 删除元素
al.remove(2);
sop(al); // 结果是: [java09,java01,java03]
// 修改元素
al.set(2,”java0007”); // 结果是: [java09,java01,java007]
// 通过角标获取元素
sop(“get(1):”+al.get(1)); // 结果是: get(1):java09
// 获取所有元素
for(intx=0;x<al.size();x++)
{
System.out.println(“al(“+x+”)=”+al.get(x));
}
// 迭代器方法获取所有元素
Iterator it = al.iterator();
while(it.hasNext())
{
sop(“next:”+it.next());
}
// 通过indexOf获取对象的位置
sop(“index=”+al.indexOf(“java01”)); // 结果为:index=1
List sub = al.subList(0,2);
sop(“sub=”+sub); // 结果为:sub=[java09,java01]
}
六、List集合中常见子类对象—— ArrayList、LinkedList、Vector
ArrayList:
底层的数据结构使用的是数组结构。特点在于查询和修改速度很快。但删除和插入慢,因为角标变。线程不同步ArrayList:
底层的数据结构使用的是数组结构。特点在于查询和修改速度很快。但删除和插入慢,因为角标变。线程不同步
LinkedList:
底层的数据结构使用的是链表数据结构。特点在于查询特别慢,但插入和删除比较快。
Vector:
底层数据结构使用数组数据结构。无论增删该查都很慢。同ArrayList功能相同,Vector出现时集合框架还没有出现。容器仅此一种。此种线程同步。ArrayList不同步。但ArrayList效率高。多线程可自己加锁。线程同步。
ArrayList默认长度是10,当超过10时,他就会new一个新的数组,长度增加50%,然后将原数组中的元素copy到新数组中来。在把新元素加到后面。
Vector默认长度为10,超过是100%延长。不如ArrayList节省空间。故Vector现在已经基本不用。枚举就是Vector特有的取出方式。Vector有迭代器、枚举、角标等取出方式。在1.0版本中。
发现枚举和迭代器很像。
Enumerationen = v.elements(); // Vector的迭代器
hasMoreElements(); nextElement(); 发现,枚举使用方式和迭代器很像
其实,枚举和迭代是一样的。因为枚举的名称以及方法的名称都过长,所以被迭代器取代了。
Vector的枚举演示:
importjava.util.*;
classVectorDemo{
public static void main(String[] args){
Vectorv = new Vector();
v.add(“java01”);
v.add(“java02”);
v.add(“java03”);
v.add(“java04”);
Enumeration en =v.elements();
while(en.hasMoreElements())
{
System.out.println(en.nextElement());
}
}
}
LinkedList链接列表(链表)
LinkedList的特有方法:
addFirst(); 将指定元素插入此列表的开头。
addLast(); 将指定元素添加到此列表的结尾。
getFirst(); 返回此列表的第一个元素。 get获取元素但不删除元素
getLast(); 返回此列表的最后一个元素。
removeFirst(); 移除并返回此列表的第一个元素。remove也可以获取元素但是元素会被删除
removeLast(); 移除并返回此列表的最后一个元素。如果集合中没有元素会出现异常。
offerFirst(); // 1.6版本后相应 将指定元素插入此列表的开头。
offerLast();
PeekFirst(); 返回此列表的第一个元素。如果没有元素返回null。
PeekLast();
pollFirst(); 移除并返回此列表的第一个元素。如果没有元素返回null。
pollLast();
前期使用get和remove方法使用的列表中没有元素,他都会抛出没有这个元素异常的提示。
注:当列表为空时,会出现NoSuchElementException异常。而到后期LinkedList升级后增加了一个新方法:pollFirst()方法用于获取并移除此列表中的第一个元素,如果此列表为空则返回null。(1.6版本出现的)
LinkedList链接列表方法演示示例:
importjava.util.*;
classLinkedListDemo{
public static void main(String[] args)
{
LinkedList link = newLinkedList();
link. addFirst (“java01”);
link. addFirst (“java02”);
link. addFirst (“java03”);
link. addFirst (“java04”);
sop(Link); // addFirst方法添加结果为:[java04,java03,java02,java01]
LinkedList link1 = newLinkedList();
link. addLast (“java01”);
link. addLast (“java02”);
link. addLast (“java03”);
link. addLast (“java04”);
sop(Link); // addLast方法添加结果为:java04]
sop(link.getFirst()); // 结果为:java04
sop(link.getLast()); // 结果为:java01
sop(“size=”+link.size()); // 获取结果为:4
sop(link.removeFirst()); // 删除 也可获取因为头元素会打印出来但被直接删除
sop(“size=”+link.size()); // 结果为:3
while(!Link.isEmpty())
{
sop(link1.removeFirst()); // 循环删除link1中的元素。
}
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}