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 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异常。(并发修改异常)
所以,在迭代时,只能用迭代器的方法操作元素,可是Iterator方法是有限的,只能对元素进行判断,取出,删除的操作,
如果想要其他的操作如添加,修改等,就需要使用其子接口,ListIterator。
该接口只能通过List集合的listIterator方法获取。
相应的示例代码如下:
package pack;
import java.util.*;
class CollectionDemo
{
public static void main(String[] args)
{
//演示列表迭代器
ArrayList al = new ArrayList();
al.add("java01");
al.add("java02");
al.add("java03");
sop("原集合:"+al);
/*
//在迭代过程中准备添加或者删除元素
for(Iterator it = al.iterator(); it.hasNext();)
{
Object obj = it.next();
if(obj.equals("java02"))
// al.add("java0007");
//那么我们只使用迭代器的方法
it.remove();//将java02的引用从集合中删除了,集合中没有java02的引用,但是obj仍然指向相应的内存地址
sop("obj="+obj);
//这里移除后仍然会打印“java02”,因此remove()只是移除了元素的引用it,而元素仍然在内存中,
//而obj之前通过it.next()指向内存中的地址,这个时候打印obj仍然会有内容。
}
//这一部抛出:java.util.ConcurrentModificationException(视频14-5,5.50处解释)
//此处并发访问,我们在用迭代器的对象obj操作元素的时候,又用集合的方法al往同一组元素里面添加元素。
//不可以既用集合又用迭代器同时操作同一组元素
sop("操作后的集合:"+al);
*/
//上面的Iterator迭代器只能有3个动作,它的子接口ListIterator,它有指针,因此它的方法较多!
ListIterator li = al.listIterator();
// sop("hasNext():"+li.hasNext());//true
// sop("hasPrevious():"+li.hasPrevious());//false
while(li.hasNext())
{
Object obj = li.next();
if(obj.equals("java02"))
// li.add("java hha");
li.set("hahah");
}
while(li.hasPrevious())
{
sop("pre:"+li.previous());//逆向获取
}
// sop("hasNext():"+li.hasNext());//false
// sop("hasPrevious():"+li.hasPrevious());//true
sop(al);
}
public static void method()
{
//由于List是接口无法创建对象,我们创建一个他的子类ArrayList的对象
ArrayList al = new ArrayList();
//添加元素
al.add("java01");
al.add("java02");
al.add("java03");
sop("原集合是:"+al);
//在这个位置添加元素
al.add(1, "java08");
sop("添加后的集合是:"+al);
//删除指定位置的元素
al.remove(2);
sop("删除后的集合是"+al);
//修改元素
al.set(2, "java haha");
sop("修改后的集合是"+al);
//通过角标获取元素
sop("角标2的元素是:"+al.get(2));
//获取所有的元素
//由于List有下标且有序,我们首先可以使用for循环通过下标来索引
for(int x=0; x<al.size(); x++)//注意,集合没有length()方法,想要获取集合的长度必须得使用size()方法
{
System.out.println("al("+x+")="+al.get(x));
}
//其次,同样可以使用迭代器来获取集合元素
for(Iterator it = al.iterator(); it.hasNext();)
{
sop(it.next());
}
//通过indexOf获取对象的位置
sop("java08的位置是:"+al.indexOf("java08"));
//获取子列表,subList(int fromIndex,int toIndex),返回列表中指定的 fromIndex(包括 )和 toIndex(不包括)之间的部分视图
//subList的返回值是List,因此这里创建List的对象,而不能是ArrayList
List sub = al.subList(0, 2);
sop("sub="+sub);
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
5、List集合常见的子类对象及其特点
List集合常见的子类如下:(数组与链表数据结构的区别,见视频14-6,1.20处解释)
|--List:元素是有序的,元素可以重复。因为该集合体系有索引。
|--ArrayList:底层的数据结构使用的是数组结构。特点:查询速度很快(改查很快,查询到就可以修改)。但是增删稍慢。线程不同步。ArrayList长度默认为10,当我们添加的长度超过10,就会new一个新的数组,长度是15(50%延长),并将原来数组中的元素copy过来,再添加新元素。(可变长度数组)
|--LinkedList:底层使用的链表数据结构。特点:增删速度很快,查询稍慢。线程不同步。
|--Vector:底层是数组数据结构。线程同步。被ArrayList替代了。因为效率低。(100%延长)
5.1、Vector类
下面我们专门说一下Vector这个类,它里面有一些特殊的东西需要介绍(枚举Enumeration)
枚举就是Vector特有的取出方式,发现枚举和迭代器很像,其实枚举和迭代是一样的。
因为枚举的名称以及方法的名称都过长,所以被迭代器取代了,枚举郁郁而终了。
相应的示例代码如下:
import java.util.*;
class CollectionDemo
{
public static void main(String[] args)
{
Vector vc = new Vector();
vc.add("java01");
vc.add("java02");
vc.add("java03");
vc.add("java04");
//element()方法返回枚举接口Enumeration的对象(多态),类似于之前的迭代器
Enumeration en = vc.elements();
while(en.hasMoreElements())
{
sop(en.nextElement());
}
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
5.2、LinkedList类
我们介绍一下LinkedList的特有方法
LinkedList:特有方法:
addFirst();
addLast();
getFirst();
getLast();
获取元素,但不删除元素。如果集合中没有元素,会出现NoSuchElementException
removeFirst();
removeLast();
获取元素,但是元素被删除。如果集合中没有元素,会出现NoSuchElementException
在JDK1.6出现了替代方法。
offerFirst();
offerLast();
peekFirst();
peekLast();
获取元素,但不删除元素。如果集合中没有元素,会返回null。
pollFirst();
pollLast();
获取元素,但是元素被删除。如果集合中没有元素,会返回null。
相应的代码如下:
package pack;
import java.util.*;
class CollectionDemo
{
public static void main(String[] args)
{
LinkedList link = new LinkedList();
//连续将4个指定元素插入链表的开头
link.addFirst("java01");
link.addFirst("java02");
link.addFirst("java03");
link.addFirst("java04");
sop(link);//[java04, java03, java02, java01]:每次在开头插入一个,前面插入的往链表后面排
LinkedList link1 = new LinkedList();
//连续将4个指定元素插入链表的结尾
link1.addLast("java01");
link1.addLast("java02");
link1.addLast("java03");
link1.addLast("java04");
sop(link1);//[java01, java02, java03, java04]:每次在结尾插入一个,前面插入的往链表前面排
//获取元素,但不删除元素
sop(link.getFirst());//java04
sop(link.getLast());//java01
sop("size="+link.size());//size=4:获取后链表长度不变
//获取元素,但是元素被删除。注意LinkedLinkList的removeFirst()方法,它不但是移除,还有删除功能
// sop(link.removeFirst());//java04:不仅仅是移除,还会获取
// sop(link.removeLast());//java01
// sop("size="+link.size());//size=2,移除后链表长度减小
//将链表中的元素全部取出:不用迭代器
while(!link.isEmpty())
{
sop(link.removeFirst());//我们取一个再删除一个,如果为空就结束循环
}
//当然也可以使用for循环判断长度,但是判断是否为空再移除的方法更加简单
for(int x=0; x<link.size(); x++)
{
System.out.println(link.get(x));
}
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
LinkList的练习如下:
/*
使用LinkedList模拟一个堆栈或者队列数据结构。
堆栈:先进后出 如同一个杯子。
队列:先进先出 First in First out FIFO 如同一个水管。
我们将LinkedList封装到堆栈/队列的类中,然后对外暴露堆栈/队列的相应方法,
使得外部通过创建堆栈/队列的对象可以调用相应的功能实现堆栈/队列的数据结构
*/
package pack;
import java.util.*;
class CollectionDemo
{
public static void main(String[] args)
{ //自己造一个容器,只不过该容器基于LinkedList容器
Queue qe = new Queue();//创建Queue对象,并为LinkedList的引用赋予对象
//先存
qe.myAdd("java01");
qe.myAdd("java02");
qe.myAdd("java03");
qe.myAdd("java04");
//取出并移除,先进先出
while(!qe.isNull())//不为空一直取出
{
System.out.println(qe.myRemove());
//结果:先进先出
// java01
// java02
// java03
// java04
}
}
}
//描述队列数据结构的类
class Queue
{
//首先创建一个LinkedList的引用,并在Queue的构造方法里面为其赋予对象
//这样在创建Queue对象的时候就可以顺便为LinkedList的对象赋值,这样不创建Queue对象的时候就没有LinkedList对象,不占内存
private LinkedList link;//创建一个私有的LinkedList对象
Queue()
{
link = new LinkedList();
}
//添加的方法:在开头添加对象
public void myAdd(Object obj)
{
link.addFirst(obj);
}
//获取并移除的方法:先进先出,那么移除末尾,并返回此移除对象
public Object myRemove()
{
return link.removeLast();//先进先出,移除最后
}
//判断是否为空
public boolean isNull()
{
return link.isEmpty();
}
}
//堆栈与队列其实同理,只不过改成先进后出即可
5.3、ArraysList类
ArrayList的练习1如下:
/*
需求:去除ArrayList集合中的重复元素。
我们创建一个singleElement方法来实现该功能,在外部创建一个需要去除重复元素的ArrayList集合
我们将这个ArrayList的引用al传入singleElement,在singleElement中设置一个临时ArrayList集合(newAl),
用al创建迭代器取al集合中的元素,如果newAl集合中不包含某个元素,就将该元素存入newAl集合,singleElement返回newAl对象
这样就可以去除al中的重复元素
*/
package pack;
import java.util.*;
class CollectionDemo
{
public static void main(String[] args)
{
ArrayList al = new ArrayList();
al.add("java01");
al.add("java02");
al.add("java01");
al.add("java03");
al.add("java04");
al.add("java02");
sop("原集合为:"+al);
al = singleElement(al);//将al集合传入singleElement方法去除重复元素再取出,返回一个去除了重复元素的ArrayList对象
sop("去除重复元素后的集合为"+al);
/*
在迭代时循环中next调用一次,就要hasNext判断一次。在循环中放多个next()会容易出错
Iterator it = al.iterator();
while(it.hasNext())
{
sop(it.next()+"...."+it.next());
}
*/
}
//实现去除重复元素的方法:传入需要去除重复元素的ArrayList对象,返回新的ArrayList对象
public static ArrayList singleElement(ArrayList al)
{
ArrayList newAl = new ArrayList();//创建一个新的ArrayList对象
Iterator it = al.iterator();//使用构造器,来遍历获取集合al中的元素。先创建一个Iterator接口的子类对象it
//在循环中,用实现Iterator的内部类对象it调用hasNext()方法遍历集合al的所有对象
while(it.hasNext())//如果al还有元素没有遍历到
{
Object obj = it.next();//使用Iterator接口的next()方法将al集合中的取出放到Object对象中
if(!newAl.contains(obj))
newAl.add(obj);//如果newAl这个集合中不包含obj,就将obj添加到newAl的集合中
}
return newAl;//newAl就是取出重复元素后的al集合
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
ArrayList的练习2如下:(难)
/*
需求:将自定义对象作为元素存到ArrayList集合中,并去除重复元素。
比如:存人对象,同姓名同年龄,视为同一个人,为重复元素。
思路:
1、对人描述,将数据封装进人对象。
2、定义容器,将人存入。
3、取出。
List集合判断元素是否相同,依据是元素的equals方法。因为contains方法在比较是否包含的时候,底层原理就是传入元素的equals方法
*/
package pack;
import java.util.*;
class CollectionDemo
{
public static void main(String[] args)
{
ArrayList al = new ArrayList();
al.add(new Person("lisi01",23));//这往里面存储的是Person类的引用:也就是Person类对象存储的地址值
al.add(new Person("lisi02",24));//Object obj = new Person("lisi02",24);
al.add(new Person("lisi03",25));
al.add(new Person("lisi01",23));
al.add(new Person("lisi02",24));
al.add(new Person("lisi04",26));
//首先,我们将Person中的元素取出来看看内容,使用迭代器先取出Person的对象
Iterator it = al.iterator();
while(it.hasNext())
{
/*
直接写:sop(it.next().getName()+"::"+it.next().getAge()); 是不行的!!!
1、首先,一次循环中next()2次,指向的不是同一个对象
2、对于al.add(new Person("lisi02",24));,add(Object obj),就是说add只能添加Object对象
那么在添加对象的时候相当于Object obj = new Person("lisi02",24);,向上类型转换了,
因此我们在用it取出的时候取的是Object对象,需要将该对象向下类型转换为Person对象才可以调用Person的获取方法
*/
/*
Object obj = it.next();//先将al中的Person对象取出,放到Person的父类Object的引用obj中(多态)
//为了使用Person类的特殊方法getName()与getAge(),我们将Object对象obj向下类型转换
Person p = (Person)obj;
*/
//上面2句可以缩写为一句
Person p = (Person)it.next();
sop("姓名:"+p.getName()+" 年龄:"+p.getAge());
}
System.out.println();
//其次我们想要取出重复元素,利用前面的方法!
// sop("原集合为:"+al);//直接打印al的对象只会打印出对象的地址值
al = singleElement(al);
Iterator it1 = al.iterator();
while(it1.hasNext())
{
Person p = (Person)it1.next();
sop("姓名:"+p.getName()+" 年龄:"+p.getAge());
}
/*
我们用前面获取集合元素的方法打印看看:发现没有去除重复!
al这个容器不知道我们判断元素相同的条件!那么他在比较的时候,只判断往里面存储的对象是否相同,
那么我们每次添加都会创建新的对象(地址值不同!),那么就算对象的内容是一样的,我们的singleElement方法也会判断其不同!
那么我们在Person中重写equals方法,使其比较name与age,那么contains比较的时候(contains底层原理是equals),
就会比较equals对象的name与age
*/
//我们将Person重写的equals方法注释,删除一个内容
sop("remove 04 :"+al.remove(new Person("lisi04",26)));//remove方法底层也是依赖于元素的equals方法。
//remove 04 :false。如果我们想删除一个元素,就得判断这个元素再内存中是否存在,而判断是否存在也是equals方法
//这里new一个新的对象与前面的地址值都不同,Person的equals没有重写比较的是地址值
}
//去除重复元素的方法
public static ArrayList singleElement(ArrayList al)
{
ArrayList newAl = new ArrayList();
Iterator it = al.iterator();
while(it.hasNext())
{
Object obj = it.next();
if(!newAl.contains(obj))//contains方法会调用Person的equals方法来比较2个对象是否相同(包含)
newAl.add(obj);
}
return newAl;
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
//首先创建一个人的类进行描述
class Person
{
private String name;
private int age;
Person(String name,int age)
{
this.name = name;
this.age = age;
}
//因为setName()与setAge()使用不到,这里省略,开发必须写
//外界获取Person类name属性的方法
public String getName()
{
return this.name;
}
//外界获取Person类age属性的方法
public int getAge()
{
return this.age;
}
//我们重写Object的equals方法,Object的equals方法比较的是对象地址,我们比较的是name与age
//该重写的equals方法是在底层自动被调用的(在contains方法处)!见下面打印出的解释,与视频14-11,13.20分钟的解释
public boolean equals(Object obj)
{//注意instanceof是关键字不是方法!不需要加"."引用
if(!(obj instanceof Person))//如果传入的要比较的类不是Person类,直接返回false
return false;//这里也可以抛出异常
Person p = (Person)obj;//先将传入的obj向下转型为Person对象
// System.out.println(this.name+"....."+p.name);
/*
* 打印结果是:
lisi02.....lisi01
lisi03.....lisi01
lisi03.....lisi02
lisi01.....lisi01
lisi02.....lisi01
lisi02.....lisi02
lisi04.....lisi01
lisi04.....lisi02
lisi04.....lisi03
见视频解释:就是我们在用contains()方法比较Person对象的时候,Person会自动调用自己的equals方法比较前面的对象
我们重写Object的equals,那么Person的equals方法比较的就是name与age,之前我们没有重写的时候,contains比较的就是对象地址!
前一个例子我们比较字符串的时候,字符串已经重写了equals,比较的是字符串内容!
*/
//这里equals与==都是在比较内容是否相同的,int型不能用equals比较(equals只能比较字符串),需要用==比较内容
//而在String中,equals方法重写用于比较字符串,那么如果本Person对象的name与age等于传入的Person对象的name和age,就返回true
return this.name.equals(p.name) && this.age == p.age;
}
}
注意,ArrayList与LinkedList在比较对象是否相同的时候,底层调用的都是equals方法,因此我们创建的对象如果要存放到ArrayList或LinkedList集合中,必须重写equals方法
参考文章:
java集合详解
java集合中的常用类
6、就业班集合补充
补充1:
如下:
// 遍历集合
for (int i = 0; i < list.size(); i++) {
}
这段代码在IDEA中直接“list.fori”回车就出来了
如果你想循环6次,就打“6.fori”回车就可以。
如果你想逆向遍历,使用list.forr+回车即可
如果想获取一个集合的迭代器,如下:
Iterator iterator = list.iterator();
IEAD中的快捷方法是:“list.iterator().var”+回车就可以直接显示
如果想使用增强for循环,IDEA中的快捷键为“list.for”
补充2:
Collection集合接口的特性以及结构如下:注意Collection是所有单列集合的父接口。
补充3:
迭代器泛型的特点
/*
1.使用集合中的方法iterator()获取迭代器的实现类对象,使用Iterator接口接收(多态)
注意:
Iterator接口也是有泛型的,迭代器的泛型跟着集合走,集合是什么泛型,迭代器就是什么泛型
*/
补充4:
迭代器实现原理,见就业班-Collection集合-07视频解析
补充5:
增强for循环
/*
增强for循环:底层使用的也是迭代器,使用for循环的格式,简化了迭代器的书写
是JDK1.5之后出现的新特性
Collectionextends Iterable:所有的单列集合都可以使用增强for
public interface Iterable实现这个接口允许对象成为 "foreach" 语句的目标。
增强for循环:用来遍历集合和数组(既普通数组与Collection集合)
格式:
for(集合/数组的数据类型 变量名: 集合名/数组名){
sout(变量名);
}
*/
补充6:
List集合是有序的,有序的意思是元素存储的顺序与取出的顺序是一致的!
List接口特点:
1. 它是一个元素存取有序的集合。例如,存元素的顺序是11、22、33。那么集合中,元素的存储就是按照11、22、33的顺序完成的)。
2. 它是一个带有索引的集合,通过索引就可以精确的操作集合中的元素(与数组的索引是一个道理)。
3. 集合中可以有重复的元素,通过元素的equals方法,来比较是否为重复的元素。
测试代码如下:
//List集合遍历有3种方式
//使用普通的for循环,使用List的get(int index)来获取角标下的元素
for(int i=0; i<list.size(); i++){
//public E get(int index):返回集合中指定位置的元素。
String s = list.get(i);
System.out.println(s);
}
System.out.println("-----------------");
//使用迭代器
Iterator<String> it = list.iterator();
while(it.hasNext()){
String s = it.next();
System.out.println(s);
}
System.out.println("-----------------");
//使用增强for
for (String s : list) {
System.out.println(s);
}
如前面所说,ArrayList集合的底层数据结构是数组,当ArrayList添加新的元素的时候,就会创建新的数组,因此Arra增删慢。
LinkedList集合的特点如下
/*
java.util.LinkedList集合 implements List接口
LinkedList集合的特点:
1.底层是一个链表结构:查询慢,增删快
2.里边包含了大量操作首尾元素的方法
注意:使用LinkedList集合特有的方法,不能使用多态
- public void addFirst(E e):将指定元素插入此列表的开头。
- public void addLast(E e):将指定元素添加到此列表的结尾。
- public void push(E e):将元素推入此列表所表示的堆栈。
- public E getFirst():返回此列表的第一个元素。
- public E getLast():返回此列表的最后一个元素。
- public E removeFirst():移除并返回此列表的第一个元素。
- public E removeLast():移除并返回此列表的最后一个元素。
- public E pop():从此列表所表示的堆栈处弹出一个元素。
- public boolean isEmpty():如果列表不包含元素,则返回true。
*/
ArrayList与Vector:Vector是线程安全的集合类,ArrayList并不是线程安全的类(因此ArrayList相对于Vector来说速度较快)。Vector类对集合的元素操作时都加了synchronized,保证线程安全。Vector与ArrayList的扩容并不一样,Vector默认扩容是增长一倍的容量,Arraylist是增长50%的容量。