集合一:Collection、Iterator、List、ArrayList、Vector、LinkedList
-------android培训、Java培训、期待与您交流!-------1 集合1.1 集合概述 集合是用来存储对象,并对多个对象进行操作的容器。 集合和数组都可以存储对象,但集合长度是可变的,而数组长度是固定的。 数组还可以存储基本数据类型,而集合只能存储对象。 实际上存放的是对象的引用(内存地址)。 Java中的集合框
1 集合
1.1 集合概述
集合是用来存储对象,并对多个对象进行操作的容器。
集合和数组都可以存储对象,但集合长度是可变的,而数组长度是固定的。
数组还可以存储基本数据类型,而集合只能存储对象。
实际上存放的是对象的引用(内存地址)。
Java中的集合框架:
Collection接口有两个子接口:List和Set。
Collection
|--List:元素是有序的,元素可以重复。因为该集合体系有索引。
|--ArrayList:底层的数据结构使用的是数组结构。特点:查询速度快,但是增删很慢。线程不同步
|--LinkedList:底层使用的链表数据结构。特点:查询速度很慢,增删速度快。
|--Vector:底层是数组数据结构。功能与ArrayList相同,但是线程同步。被ArrayList替代(多线程加锁)
|--Set:元素是无序的,元素不可以重复。无序:存入和取出的顺序不一定一致。
|--HashSet:数据结构是哈希表,线程是非同步的。保证元素唯一性的原理:判断元素的hashCode值是否相同。如果相同,还会继续判断元素的equals()方法,是否为true。
|--TreeSet:可以对Set集合中的元素进行排序,底层数据结构是二叉树。保证元素唯一性的依据:compareTo()方法的return 返回值是0,即: return 0;
1.2 集合Collection共性方法
1,boolean add(e):
将指定的元素添加到此列表的尾部,即添加一个对象到集合尾部,e是要添加到此列表中的元素(任意类型),返回true。
2,boolean remove(Object o):
移除此列表中首次出现的指定元素(如果存在)。如果此列表包含指定的元素,则返回true。
3,void clear():
移除此列表中的所有元素。
4,int size():
返回此列表中的元素数,即集合中对象的个数。
5,boolean contains(Object o):
如果此列表中包含指定元素,则返回true,即如果此集合中包含o这个元素,则返回true。
6,boolean isEmpty():
如果此列表没有元素,返回true,即是个空的集合,返回true。
7,boolean retainAll(Collection c):
移除当前集合中未包含在集合c中的所有元素,取交集。如果当前集合因为调用发生更改,则返回true。
8,boolean removeAll(Collection c):
移除当前集合中,两个集合的交集,即去掉交集。如果当前集合因为调用发生更改,则返回true。
9,boolean containsAll(Collection c):
如果当前集合包含集合c中的所有元素,则返回true。
10,boolean addAll(Collection c):
将集合c添加到当前集合的尾部,如果当前集合因为调用发生更改,则返回true。
1.3 迭代器Iterator
什么是迭代器呢?
其实就是集合的取出元素的方式,用来操作集合。
Iterator<T> iterator();
Iterator接口:把取出方式定义在集合的内部,这样取出方式就可以直接访问集合内容的元素,那么取出方式就被定义成了内部类。
而每一个容器的数据结构不同,所以取出的动作细节也不一样,但是都有共性内容(判断和取出),把共性内容封装为Iterator接口。
那么如何获取集合的取出对象呢? 通过一个对外提供的方法 iterator();
Iterator it = collection.iterator();
boolean hasNext();
Object next();
void remove();
集合共性方法和迭代器示例:
import java.util.*;
class CollectionDemo{
public static void main(String[] args){
method_3();
}
public static void sop(Object obj){
System.out.println(obj);
}
public static void method_1(){
//创建一个集合容器,使用Collection接口的子类。ArrayList
ArrayList al = new ArrayList();
//1,添加元素
al.add("java01"); //add(Object obj);
al.add("java02");
al.add("java03");
al.add("java04");
//打印原集合
sop(al);
//3,删除元素
al.remove("java02");
al.clear(); //清空集合
//4,判断元素
sop("java03是否存在:"+al.contains("java03"));
sop("集合是否为空:"+al.isEmpty());
//2,获取个数,集合长度。
sop("size=:"+al.size()); //集合的size()代替了length(),获取长度
sop(al);
}
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("java03");
al2.add("java04");
al2.add("java05");
al2.add("java06");
al1.retainAll(al2); //取交集,al1中只会保留和al2中相同的元素。
sop("al1:"+al1);
sop("al2:"+al2);
}
public static void method_3(){ //迭代器
ArrayList al3 = new ArrayList();
al3.add("java01");
al3.add("java02");
al3.add("java03");
al3.add("java04");
Iterator it = al3.iterator();
while(it.hasNext()){
sop(it.next());
}
/* 节约内存的写法,循环结束 it对象即消亡
for(Iterator it = al3.iterator(); it.hasNext(); ){
sop(it.next());
} */
}
}
2 List集合
List是Collection接口的一个子接口,List集合也是集合的一种。
|--List:元素是有序的,元素可以重复。因为该集合体系有索引。
|--ArrayList:底层的数据结构使用的是数组结构。特点:查询速度快,但是增删很慢。线程不同步。
|--LinkedList:底层使用的链表数据结构。特点:查询速度很慢,增删速度快。
|--Vector:底层是数组数据结构。功能与ArrayList相同,但是线程同步。被ArrayList替代(多线程加锁)。
2.1 List集合的特有方法
List集合特有方法:凡是可以操作脚标index的方法都是该体系特有的方法。
增:
add(index,element):在集合的index位置(脚标)添加元素。
addAll(index,Collection):在集合的index位置(脚标)添加一个集合。
删:
remove(index):删除集合中位置index上的元素。
改:
set(index,element):修改集合index位置上的元素为element。
查:
get(index):获取指定位置上的元素。
subList(from,to):获取从from位置到(to-1)位置上的子集合,包括首不包括尾。
listIterator():获取ListIterator迭代器,ListIterator是Iterator的子接口,是List集合特有的迭代器。
2.2 List集合特有迭代器ListIterator
List集合特有的迭代器,ListIterator是Iterator的子接口。
在迭代时,不可以通过集合对象的方法操作集合中的元素,因为会发生并发修改异常:ConcurrentModificationException。
所以在迭代时,只能用迭代器的方法操作元素,可是Iterator的方法是有限的,只能对元素进行判断、取出、删除的操作。
如果想要其他的操作如添加、修改等,就需要使用其子接口,ListIterator。
该接口只能通过List集合的listIterator方法获取。
List集合特有方法的代码示例:
import java.util.*;
class ListDemo{
public static void main(String[] args){
method_ListIterator();
}
public static void sop(Object obj){
System.out.println(obj);
}
public static void method(){
ArrayList al1 = new ArrayList(); //创建集合容器
al1.add("java01"); //添加元素
al1.add("java02");
al1.add("java03");
al1.add("java04");
sop("原集合是:"+al1);
al1.add(1,"java05"); //增:在指定位置添加元素
al1.remove(2); //删:删除指定位置的元素
al1.set(2,"java007"); //改:修改元素
sop(al1);
sop("get(1):"+al1.get(1));//查:获取指定元素
for(int x=0; x<al1.size(); x++){ //获取全部元素
sop("al1("+x+"):"+al1.get(x));
}
for(Iterator it=al1.iterator(); it.hasNext(); ){ //迭代获取全部
sop(it.next());
}
//通过indexOf()获取对象的位置
sop("java007位置:"+al1.indexOf("java007"));
List sub = al1.subList(1,3); //包括首,不包括尾
sop("sub:"+sub);
}
public static void method_Iterator(){
ArrayList al2 = new ArrayList(); //创建集合容器
al2.add("java01"); //添加元素
al2.add("java02");
al2.add("java03");
sop("原集合是:"+al2);
Iterator it = al2.iterator();
while(it.hasNext()){
Object obj = it.next();
if(obj.equals("java02"))
//al2.add("java08"); 并发异常,集合和迭代器不能同时操作
it.remove(); //将java02的引用从集合中删除了,但对象还在内存中
sop("obj="+obj);
}
sop(al2);
}
public static void method_ListIterator(){
ArrayList al3 = new ArrayList(); //创建集合容器
al3.add("java01"); //添加元素
al3.add("java02");
al3.add("java03");
sop("原集合是:"+al3);
ListIterator li = al3.listIterator(); //获取ListIterator迭代器。
while(li.hasNext()){
Object obj = li.next();
if(obj.equals("java02"))
li.add("java008"); //set,remove
}
sop(al3);
}
}
2.3 ArrayList集合
ArrayList集合底层的数据结构使用的是数组结构。
特点:查询速度快,但是增删很慢。
ArrayList是线程不同步。
ArrayList拥有Collection集合中的共性方法,以及List集合的特有方法。
代码示例可以参考本文第一段代码Demo。
2.4 Vector集合
Vector类是List接口的子类,当然也实现了集合Collection接口。
Vector集合的底层数据结构是数组。功能与ArrayList相同,但是Vector线程同步。
可以被ArrayList替代(多线程加锁后)。
Vector中的枚举:
枚举就是Vector特有的取出方式。
枚举和迭代器很像,其实枚举和迭代器是一样的。
因为枚举的名称以及方法的名称都过长,所以被迭代器取代了。
(优先考虑Iterator接口,而不是Enumeration。)
Vector代码示例:
import java.util.*;
class VectorDemo{
public static void main(String[] args){
Vector v = new Vector();
v.add("java01");
v.add("java02");
v.add("java03");
v.add("java04");
Enumeration en = v.elements(); //Vector的elements方法返回一个枚举
while(en.hasMoreElements()){ //hasMoreElements是否有更多元素
System.out.println(en.nextElement()); //nextElement返回下一个元素
}
}
}
2.5 LinkedList集合
LinkedList集合底层使用的是链表数据结构。
特点:查询速度很慢,增删速度快。
LinkedList集合特有方法:
addFirst():在头部添加一个元素。
addLast():在尾部添加一个元素。
getFirst():get获取元素但不删除元素,获取列表第一个元素。
getLast():获取列表末尾的元素。
removeFirst():获取并且删除第一个元素。
removeLast():获取并且删除最后一个元素。
如果get、remove时,列表为空没有元素,抛出NoSuchElementException异常。
在JDK1.6中出现了替代方法(替代列表为空时抛出异常):
offerFirst():offer替代了add,在此列表的开头插入指定的元素。
offerLast():在此列表末尾插入指定的元素。
peekFirst():peek替代了get,获取但不移除此列表的第一个元素;如果此列表为空,则返回 null。
peekLast():获取但不移除此列表的最后一个元素;如果此列表为空,则返回 nul。
pollFirst():poll替代了remove,获取并移除此列表的第一个元素;如果此列表为空,则返回 null。
pollLast():获取并移除此列表的最后一个元素;如果此列表为空,则返回 null。
如果peek、poll时,列表为空没有元素,不再抛出异常,而是返回null。
LinkedList集合的代码示例:
import java.util.*;
class LinkedListDemo{
public static void main(String[] args){
LinkedList link = new LinkedList();
link.addLast("java01");
link.addLast("java02");
link.addFirst("java03");
link.addFirst("java04");
sop(link);
sop(link.getFirst()); //获取第一个元素
sop(link.getLast());
sop("size="+link.size());
sop(link.removeFirst()); //获取并删除第一个元素
sop("size="+link.size());
while(!link.isEmpty()){ //使用LinkedList特有方法,相当于迭代器Iterator
sop(link.removeFirst());
}
}
public static void sop(Object obj){
System.out.println(obj);
}
}
3 集合的小练习
3.1 LinkedList集合的练习
LinkedList集合的一个小练习,要求掌握。
需求:使用LinkedList模拟一个堆栈或者队列数据结构。
堆栈:先进后出。
队列:先进先出。
LinkedList练习的代码示例:
import java.util.*;
class LinkedListTest{
public static void main(String[] args){
DuiZhan d = new DuiZhan(); //堆栈
d.myAdd("java01");
d.myAdd("java02");
d.myAdd("java03");
d.myAdd("java04");
sop(d);
while(!d.isNull()){
sop(d.myGet());
}
}
public static void sop(Object obj){
System.out.println(obj);
}
}
class DuiLie{ //模拟队列,先进先出。
LinkedList link;
DuiLie(){
link = new LinkedList();
}
public void myAdd(Object obj){ //队列中在末尾添加元素。
link.addLast(obj);
}
public Object myGet(){ //队列中在头部删除元素。
return link.removeFirst();
}
public boolean isNull(){
return link.isEmpty();
}
}
class DuiZhan{ //模拟堆栈,先进后出。
LinkedList link;
DuiZhan(){
link = new LinkedList();
}
public void myAdd(Object obj){ //堆栈中在末尾添加元素。
link.addLast(obj);
}
public Object myGet(){ //堆栈中在末尾删除元素。
return link.removeLast(); //这里与队列不同
}
public boolean isNull(){
return link.isEmpty();
}
}
3.2 ArrayList集合的练习1
需求:去除ArrayList集合中的重复元素。
死路:定义一个新集合,遍历原集合的元素,如果新集合中没有此元素,则不重复,添加。如果新集合中已有此元素,则重复,不添加。
代码示例:
import java.util.*;
class ArrayListTest{
public static void main(String[] args){
ArrayList al = new ArrayList();
al.add("java01");
al.add("java02");
al.add("java01");
al.add("java02");
al.add("java03");
sop(al);
al = singleElement(al); //去除重复元素
sop(al);
Iterator it = al.iterator(); //迭代循环中next调用一次,就要hasNext判断一次。
while(it.hasNext()){
sop(it.next());
//sop(it.next()+"..."+it.next()); //不能一次循环调用两次next();
}
}
public static void sop(Object obj){
System.out.println(obj);
}
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))
newAl.add(obj);
}
return newAl;
}
}
3.3 ArrayList集合的练习2
需求:将自定义对象作为元素存到ArrayList集合中,并去除重复元素。
比如:存人对象。同姓名同年龄,视为同一个人,为重复元素。
思路:
1,对人进行描述,将数据封装进人对象。
2,定义容器,将人存入。
3,取出。
注意:List集合判断元素是否相同,依据是元素的equals()方法,即Object父类的equals()方法,有时需要重写equals(),contains()、remove()都依赖equals()方法。
代码示例(主要集合中的多态:add()中添加的是Object类型,如果要用自定义方法,需向下转型):
import java.util.*;
class ArrayListTest2{
public static void main(String[] args){
ArrayList al = new ArrayList();
al.add(new Person("lisi01",30)); //al.add(Object,obj); //Object obj = new Person("lisi01",30);
al.add(new Person("lisi02",32));
al.add(new Person("lisi02",32));
al.add(new Person("lisi03",36));
///sop(al);
al = singleElement(al); //去除重复元素
Iterator it = al.iterator();
while(it.hasNext()){
Object obj = it.next();
Person p = (Person)obj; //next得到的是Object类型,向下转型为Person,才能调用Person自定义方法
sop(p.getName()+"..."+p.getAge());
}
}
public static void sop(Object obj){
System.out.println(obj);
}
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)) //Collection接口中contains()的原理就是equals();
newAl.add(obj);
}
return newAl;
}
}
class Person{
private String name;
private int age;
Person(String name,int age){
this.name = name;
this.age = age;
}
public String getName(){
return name;
}
public int getAge(){
return age;
}
public boolean equals(Object obj){ //重写equals(),自定义两个对象相同的规则,用来去重。
if(!(obj instanceof Person))
return false;
Person p = (Person)obj;
System.out.println(this.name+"..."+p.name);
return this.name.equals(p.name) && this.age == p.age;
}
}
更多推荐
所有评论(0)