1、集合类特点
为什么出现集合类?
- 面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,就对对象进行存储,集合就是存储对象最常用的一种方式。
数组和集合类同是容器,有何不同?
- 数组虽然也可以存储对象,但长度是固定的;集合长度是可变的。
数组中可以存储基本数据类型,集合只能存储对象。(我们看到集合也可以存储基本数据类型是因为在向集合添加基本数据类型数据的时候会自动装箱)
集合类的特点
- 集合只用于存储对象,集合长度是可变的,集合可以存储不同类型的对象。
2、集合类的分类
集合类的框架:集合框架,集合框架的结构如下:
Java集合框架主要包括两种类型的容器,一种是集合(Collection),另一种是图(Map)。Collection接口又有多个子接口,其中较为重要的是List、Set和Queue接口,再下面是一些抽象类,最后是具体实现类,常用的类有List——ArrayList、LinkedList、Vector,Set——HashSet(下面又有LinkedHashSet)、TreeSet;Map接口下面又有HashMap类(下面又有LinkedHashMap)、TreeMap类等。
为什么会出现这么多的容器呢? 因为每一个容器(集合)对数据的存储方式都有不同,这个存储方式称之为:数据结构,既数据在内存中的存储方式。
3、集合框架Collection的共性方法
Collection接口的共性方法,以ArrayList类为例。(视频14-2中有各类方法的粗略解读)
Collection定义了集合框架的共性功能。
1,添加
add(e);
addAll(collection);
2,删除
remove(e);
removeAll(collection);
clear();
3,判断。
contains(e);
isEmpty();
4,获取
iterator();
size();
5,获取交集。
retainAll();
6,集合变数组。
toArray();
1、add方法的参数类型是Object。以便于接收任意类型对象。
2、集合中存储的都是对象的引用(地址),而不是对象实体!(见视频14-12,10.10开始的地方有解释)
什么是迭代器呢?
其实就是集合的取出元素的方式,如同抓娃娃游戏机中的夹子。(视频14-3,6.42开始的迭代器的特点!)
每一个集合的数据结构不同,导致他们的存取方式不同,而且一个集合取出方式不足以用一个方法来描述(取出要有判断有没有,取出等功能),
因此我们取出的多个功能封装到一个对象中,每个容器中都有一个取出对象,不同容器的取出对象的取出动作也不一样。为了描述取出对象,我们用一个类来描述取出方式。
该类定义在集合的内部,那么取出方式就被定义成了内部类,这样取出方式就可以直接访问集合内容的元素。
而每一个容器的数据结构不同,所以取出的动作细节也不一样,但是都有共性内容判断和取出,那么可以将写共性抽取。
那么这些内部类都符合一个规则,该规则抽取出来是接口Iterator,我们可以通过一个集合对外提供的方法iterator()方法来获取集合的取出对象,
该iterator()方法返回集合实现Iterator接口的内部类的对象(多态)(如AbstractList类中iterator()方法返回new Itr(),而Itr()类实现了Iterator接口并重写Iterator里面的方法,这些方法适用于AbstarctLIst的数据结构)。
这样我们就可以在集合外面,通过调用集合实现的接口Iterator的方法来调用集合的取出方法,而且针对不同集合的不同数据结构,不同集合对Iterator接口方法的实现方式不同。
迭代器是取出方式,会直接访问集合中的元素,所以将迭代器通过内部类的形式来进行描述,通过容器的iterator()方法获取该内部类的对象。
相应的代码示例如下:
package pack;
import java.util.*;//记得处理看java.lang包之外,其他包必须得手动导入。
class CollectionDemo
{
public static void main(String[] args)
{
// CollectionDemo.method_2();
CollectionDemo.method_get();
}
//获取方法
//iterator()方法,返回接口:Iterator<E> iterator():返回按适当顺序在列表的元素上进行迭代的迭代器。
public static void method_get()
{
ArrayList al = new ArrayList();
al.add("java01");
al.add("java02");
al.add("java03");
al.add("java04");
//由于接口无法创建对象,接口型的引用只能指向它的子类对象(多态)
//iterator()方法返回Iterator接口的子类对象(重写了Iterator接口的方法),这样就可以使用接口Iterator的方法
Iterator it = al.iterator();//获取迭代器,用于取出集合中的元素
while(it.hasNext())//hasNext():如果仍有元素可以获取
{
sop(it.next());//获取元素,next():返回迭代的下一个元素。
}
//运行结束it对象还在内存中
//上面代码的规范写法
for(Iterator it1 = al.iterator();it1.hasNext();)
{
sop(it1.next());
}
//运行结束for()循环结束,那么it1也会自动被清除
}
//获取集合交集的方法/移除集合交集方法
public static void method_2()
{
ArrayList al1 = new ArrayList();
al1.add("java01");
al1.add("java02");
al1.add("java03");
al1.add("java04");
ArrayList al2 = new ArrayList();
al2.add("java01");
al2.add("java02");
al2.add("java05");
al2.add("java06");
// al1.retainAll(al2);
// sop(al1);//[java01, java02]:仅保留集合al1与al2的交集部分,并存储在al1中
// sop(al2);//[java01, java02, java05, java06]
//retainAll():仅在列表中保留指定 collection 中所包含的元素(可选操作)。
al1.removeAll(al2);
sop(al1);//[java03, java04]:移除集合al1与al2的交集部分,并将结果存储在al1中
sop(al2);//[java01, java02, java05, java06]
//从列表中移除指定 collection 中包含的其所有元素(可选操作)。
}
//基本方法
public static void base_method()
{
//创建一个集合容器。使用Collection的子类ArrayList
ArrayList al = new ArrayList();
//添加元素
//集合只能存储对象,不能存储基本数据类型,而字符串就是一种对象(String类对象),其他基本数据类型也可以通过他们的包装类创建对象
al.add("java02");
al.add("java01");
al.add("java03");
al.add("java04");
//打印原集合对象:会直接将集合的内容打印出来
sop(al);//结果:[java01, java02, java03, java04]
//删除元素
// al.remove("java02");
// al.clear();//清空集合
//打印改变后的集合
// sop(al);
//获取集合长度
// sop("size:"+al.size());
//判断元素
sop("java03是否存在:"+al.contains("java03"));
sop("集合是否为空:"+al.isEmpty());
//add(Object obj)(E e)是泛型,我们暂时理解为(Object obj),为什么使用Object obj
//因为容器添加的对象是类类型的,所以只能使用上帝父类Object来作为参数(多态)
//向集合中存储对象时内存的存储情况:14-12,10.10开始的地方有解释。集合存储的是对象在堆中的地址值。
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
4、List集合的共性方法
List集合的方法与特点如下
Collection
|--List:元素是有序的,元素可以重复。因为该集合体系有索引。
|--ArrayList:底层的数据结构使用的是数组结构。特点:查询速度很快。但是增删稍慢。线程不同步。
|--LinkedList:底层使用的链表数据结构。特点:增删速度很快,查询稍慢。线程不同步。
|--Vector:底层是数组数据结构。线程同步。被ArrayList替代了。因为效率低。
|--Set:元素是无序,元素不可以重复。、
List:特有方法。凡是可以操作角标的方法都是该体系特有的方法。而Set无序不重复,没有角标可以操作。
增
add(index,element);
addAll(index,Collection);
删
remove(index);
改
set(index,element);
查(获取)
get(index):
subList(from,to);
int indexOf(obj):获取指定元素的位置。
ListIterator listIterator();
List集合特有的迭代器:ListIterator是Iterator的子接口。
在迭代时,不可以通过集合对象的方法操作集合中的元素,因为会发生ConcurrentModificationException异常。(并发修