您的位置:首页 > 职场人生

黑马程序员——集合框架collection集合接口及List子类

2015-07-30 01:00 651 查看
——- android培训java培训、期待与您交流! ———-



所谓框架就是一个类库的集合。集合框架就是一个用来表示和操作集合的统一的架构, 包含了实现集合的接口与类。

java.util 包中包含了一些在 Java 2 中新增加增强功能:

类集。一个类集(collection)是一组对象。

类集的增加使得许多 java.util 中的成员在结构和体系结构上发生 根本的改变。它也扩展了包可以被应用的任务范围。类集是被所有 Java 程序员紧密关注的 最新型的技术。

除了类集,java.util 还包含了支持范围广泛的函数的各种各样的类和接口。这些类和接 口被核心的 Java 包广泛使用,同时当然也可以被你编写的程序所使用。对它们的应用包括 产生伪随机数,对日期和时间的操作,观测事件,对位集的操作以及标记字符串。由于 java.util 具有许多特性,因此它是 Java 中最被广泛使用的一个包。

list set Map的区别



一.集合类和数组的异同

1、数组特点高效、保存基本类型,集合带array的底层由数组实现,还有一部分由链表或者树

2、数组大小固定(巨大缺点,内存中一定连续),集合各的长度是可变的!

3.数组定义时需要指定类型,只能存储同一类型的数据,而集合不限定类型

4、数组可以存储基本数据类型,集合只能存储不同类型对象。

5、集合放原始类型其实是通过装箱拆箱来实现的,以前原生类型只能用数组,现在集合也可以,所以现在基本上除了性能外,均推荐使用集合。

二.获取collection集合中的元素的方法for循环和Iterator迭代器(常用)

迭代器:

对 collection 进行迭代的迭代器。

1. 使用方法iterator()要求容器返回一个Iterator。第一次调用Iterator的next()方法时,它返回序列的第一个元素。

2. iterator()方法是java.lang.Iterable接口,被Collection继承。

Iterator的方法

  (2) E next()获得序列中的下一个元素。

  (3) boolean hasNext()检查序列中是否还有元素。

  (4) void remove()将迭代器新返回的元素删除(可选操作)。

使用迭代器示例代码内容如下:

import java.util.*;
class IteDemo
{
public static void main(String[] args)
{
method_1();
}
public static void method_1()
{
ArrayList a1= new ArrayList();
a1.add("java01");
a1.add("java02");
a1.add("java03");
a1.add("java04");

Iterator it=a1.iterator();//1.获取迭代器,用于取出集合中的元素

while(it.hasNext())//2.接口Iterator中的一个方法返回loolean,如果有元素可以迭代,返回true,否则false,
{
sop(it.next());//it.next(),3.返回迭代的下一个元素
}//判断是否有元素,没有则停止输出。
for(Iterator in=a1.iterator();in.hasNext();)//使用完释放对象
{
sop(in.next());//获取序列中的下一个元素
}//可以用for或者while循环来完成迭代器获取集合里所有元素
}//for循环更优化
public static void sop(Object obj)
{
System.out.println(obj);
}
}


编译如图:



List集合特有的迭代器。ListIterator是Iterator的子接口。

在迭代时不可以通过集合对象的方法操作集合中的元素,会发生并发修改异常。

所以在迭代时只能用迭代器的方法操作元素。

Iterator方法是有限的,只能对元素进行判断,取出,删除的操作

如果想要其他的操作ru:添加,修改等,就需要使用其子接口ListIterator

该接口只能通过List集合的List集合的ListIterator方法获取

Iterator和ListIterator主要区别:

1、ListIterator有add()方法,可以向List中添加对象,而Iterator不能。

2、ListIterator和Iterator都有hasNext()和next()方法,可以实现顺序向后遍历。但是ListIterator有hasPrevious()和previous()方法,可以实现逆向(顺序向前)遍历。Iterator就不可以。

3、ListIterator可以定位当前的索引位置,nextIndex()和previousIndex()可以实现。Iterator 没有此功能。

4、都可实现删除对象,但是ListIterator可以实现对象的修改,set()方法可以实现。Iterator仅能遍历,不能修改。因为ListIterator的这些功能,可以实现对LinkedList等List数据结构的操作。

ListIterator方法摘要:(list集合特有的迭代器

void add(E e)

|- - - - - 将指定的元素插入列表(可选操作)。

boolean hasNext()

|- - - - - 以正向遍历列表时,如果列表迭代器有多个元素,则返回 true(换句话说,如果 next 返回一个元素而不是抛出异常,则返回 true)。

boolean hasPrevious()

|- - - - - 如果以逆向遍历列表,列表迭代器有多个元素,则返回 true。

E next()

|- - - - - 返回列表中的下一个元素。

int nextIndex()

返回对 next 的后续调用所返回元素的索引。

E previous()

|- - - - - 返回列表中的前一个元素。

int previousIndex()

|- - - - - 返回对 previous 的后续调用所返回元素的索引。

void remove()

|- - - - - 从列表中移除由 next 或 previous 返回的最后一个元素(可选操作)。

void set(E e)

|- - - - - 用指定元素替换 next 或 previous 返回的最后一个元素(可选操作)。

操作方法见后面Linkedlist内容讲解

与for循环的区别

for循环获取集合中的元素适合适用于Arraylist

一般for循环需要事先知道循环的次数。

高级for(JDK1.5以后)循环其实就是底层原理还是迭代器,优点:简化书写,只能读取,不能获取下角标(迭代器可以通过ListIterator完成添加修改)

示例:

ArrayList hs =new ArrayList();

hs.add("java03");
hs.add("java04");
hs.add("java01");
//使用高级for循环
for(String s:hs)
{
System.out.println(s);
}


三.collection集合的共性方法

注:1,add方法的参数类型是Object,以便于接收任意类型的对象。

2,集合中存储的都是对象的引用(地址)

常用共性方法见代码块:

创建一个集合容器。使用Coolection接口的子类。
ArrayList a1= new ArrayList();

//1,添加元素。
a1.add("java01");//add(Object obj)
a1.add("java02");
a1.add("java03");
a1.add("java04");

//打印集合
sop("原集合"+a1);//打印[java01,java02,java03,java04]

//3.删除元素。
sop(a1.remove("java02"));//打印[java01,java03,java04]
sop("现集合"+a1);

//判断元素。
sop("java03是否存在:"+a1.contains("java02"));
//false "java02"已经被删除。
sop("集合是否为空"+a1.isEmpty());//false 集合不为空

//4.清空集合
a1.clear();
//5.获取个数,集合长度。
sop("size="+a1.size());
------------------------------------------------------
ArrayList a1= new ArrayList();
a1.add("java01");
a1.add("java02");
a1.add("java03");
a1.add("java04");
sop("原来的a1"+a1);

ArrayList a2= new ArrayList();
a2.add("java01");
a2.add("java02");
a2.add("java05");
a2.add("java06");
a1.retainAll(a2);//求交集,a1中只有与a2相同的元素。a2不变
sop("a1.retainAll(a2)后的a1"+a1);
sop("a1.retainAll(a2)后的a2"+a2);*/


四.List集合

Collection

|—List;元素是有序的,元素可以重复,因为该集合体系有索引。

———|—ArrayList :底层的数据结构使用的是数组结构。特点:查询速度很快,但增删较慢。,线程不同步,长度为10,50%延长

——–|—LinkedList :底层使用的链表数据结构。采用的将对象存放在独立的空间中,而且在每个空间中还保存下一个链接的索引特点:增删很快,查询慢

——–|—Vector:底层是数组数据结构,线程同步。beiArrayList替代了。长度为10.超过100%延长

|—set;元素是无序的,元素不可以重复。(子类待下篇日记总结)

List:

特有方法:凡是可以操作角标的方法都是该体系特有的方法



add(index,element);//指定位置插入元素

addAll(index,Collsction);//添加指定 collection 中的所有元素到此列表的结尾顺序是迭代器返回这些元素的顺序



remove(index); //移除指定位置的元素



set(index,element); //指定元素替换指定位置的元素



get(index); //返回指定位置的元素

subList(from,to);//返回指定位置含头不含尾的元素

listIterator();//返回次列表元素的列表迭代器(专用迭代器)

indexOf(Object o) //返回次列表的第一次出现指定元素的所以,若没有返回-1

部分操作代码如下:

import java.util.*;
class  CollectionDemo3
{
/*
public static void main(String[] args)
{
ArrayList a1=new ArrayList();
//添加元素
a1.add("java01");
a1.add("java02");
a1.add("java03");
a1.add("java04");
sop("原来集合是=  "+a1);
//[java01, java02, java03, java04]
//添加指定位置的元素
a1.add(1,"java09");
sop("1位置添加后是=   "+a1);
//[java01, java09, java02, java03, java04]
//删除指定位置的元素
a1.remove(2);
sop("删除2位置后是=   "+a1);
//[java01, java09, java03, java04]
//修改指定位置的元素
a1.set(2,"java000");
sop("修改2位置的后是=   "+a1);
//[java01, java09, java000, java04]

//通过角标获取相应元素
sop("get(1);  "+a1.get(1));
//java09
//获取所有元素
for(int x=0;x<a1.size();x++)
{sop("a1("+x+")=  "+a1.get(x));}
//a1(0)=  java01
// a1(1)=  java09
// a1(2)=  java000
// a1(3)=  java04

//使用迭代器获取
for(Iterator in=a1.iterator();in.hasNext();)//使用完释放对象
{
sop("next:  "+in.next());
}
//next=  java01
//next=  java09
// next=  java000
// next=  java04

//通过indexOf获取对象的位置
sop("index= "+a1.indexOf("java02"));//"java02"不存在所以返回-1

//通过subList获取对象的位置

sop("sub= "+a1.subList(1,3));//[java09,java000],含头不含尾

}
*/

public static void main(String[] args)
{
ArrayList a1=new ArrayList();
a1.add("java01");
a1.add("java02");
a1.add("java03");
a1.add("java04");
sop("a1前=  "+a1);
//a1前=  [java01, java02, java03, java04]

//该例中使用的是Iterator,有缺陷
//在迭代器操作时又用集合的方法操作元素会产生安全隐患 此为并发访问
Iterator it=a1.iterator();//该迭代器无添加功能
while(it.hasNext())//有元素返回true
{
Object obj=it.next();
if(obj.equals("java02"))
it.remove();//将“java02”的引用从集合中删除了。
sop("obj= "+obj);
}
sop("a1后= "+a1);
//a1后= [java01, java03, java04]
}
public static void sop(Object obj)
{
System.out.println(obj);
}

}


List集合特有的额迭代器,ListIterator是Tierator的子接口

在迭代时,用集合对象的方法操作元素会发生

ConcurrentModificationException异常(并发修改异常)

Itreator方法是有限的,只能判断,取出,删除操作

他的子类ListIteerator还具备插入add、逆向遍历hasPrevious()、替换set(E e)等增删改查操作

示例见代码块:

ArrayList a1=new ArrayList();

a1.add(“java01”);

a1.add(“java02”);

a1.add(“java03”);

a1.add(“java04”);

ListIterator li=a1.ListIterator();

while(li,hasNext)

{

Object obj=li.next();

fi(obj.equals(“java02”))

//li.add(“java009”);//”java02”后面添加”java009”

li.set(“java006”);//将“java02”修改为“java006”;

}

只有list才具备这个功能因为list集合元素都带角标

ArrayList和LinkedList的大致区别:

1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。

2.对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。

3.对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。

五.LInkedList

ArrayList和LinkedList的大致区别:

1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。

2.对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。

3.对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。

链表结构

linkedlist常用特有方法

addFirst();从头添加

addLast();从尾添加

getFirst();

getLast();

获取元素,不删除元素

removeFirst();

removeLast();

获取元素,删除元素,长度减少。

如果集合中没有元素会出现NoSuchElementException

在JDK1.6出现了替代方法

offerFirst();

offerLast();

peekFirst();

peekLast();

获取元素,不会删除元素,如果集合中本没有元素,会返回null

pollFirst();

pollLast();

获取元素,会删除元素,如果集合中本没有元素,会返回null

操作代码示例:

class  LinkedListDemo
{
public static void main(String[] args)
{
LinkedList link=new LinkedList();

link.addFirst("java01");
link.addFirst("java02");
link.addFirst("java03");
link.addFirst("java04");
//java04,java03,java02,java01
sop(link.removeFirst());//java04,**移除的是列表开头的元素
sop(link);//[ java03, java02, java01]
link.addLast("java01");//从链表后面往前塞
link.addLast("java02");
link.addLast("java03");
link.addLast("java04");
sop(link);//[ java03, java02, java01, java01, java02, java03, java04]

sop("size= "+link.size());//打印link的长度。

}
public static void sop(Object obj)
{
System.out.println(obj);
}
}


编译如下:



补充:LinkedList实现了List接口,容许null元素。此外LinkedList供给额外的get,remove,办法在LinkedList的首部或尾部。这些操纵使LinkedList可被用作客栈(stack),队列(queue)或双向队列(deque)。

  LinkedList没有同步办法(线程不安全)。若是多个线程同时接见一个List,则必须本身实现接见同步。一种解决办法是在创建List机会关一个同步的List:

    List list = Collections.synchronizedList(new LinkedList());

需求:

使用LinkedList模拟一个堆栈或者队列数据结构

堆栈,先进后出,如同杯子

队列;先进先出 First in First out FIFO 如同一个水管。

代码如下:

import java.util.*;
class LinkedList1
{
private LinkedList link;
LinkedList1()
{
link=new LinkedList();
}
public void myAdd(Object obj)//定义从头添加元素的函数
{
link.addFirst(obj);
}
public Object myGet()//定义从头取函数的方式
{                   //获取元素,删除元素,长度减少。
return link.removeFirst();
}
public boolean isNull()//判断是否为空,是否取完
{
return link.isEmpty();
}
}
class LinkedListDemo1
{
public static void main(String[] args)
{
LinkedList1 d1=new LinkedList1();
d1.myAdd("java01");//调用myAdd()函数依次添加元素
d1.myAdd("java02");
d1.myAdd("java03");
d1.myAdd("java04");
while(!d1.isNull())
System.out.println(d1.myGet());
}
}


编译结果:



需求:

将自定义对象作为元素存储到集合中,并去除重复元素

同姓名,年龄的为同一人

思路;创建人对象,有姓名有年龄

定义容器进行封装

取出元素

List集合判断元素是否相同,依据的是元素的equals方法,其他的集合不一样

contains方法和remove方法都默认调用Object中的equals方法

六.Vector

枚举是Vector特有的取出方法

发现枚举和迭代器很像。

其实枚举和迭代是一样的

因为枚举的名称以及方法的名称都过长

所以被迭代器取代了。

 Vector也是数组结构,类似ArrayList,然则Vector是同步的(线程安全)。由Vector创建的Iterator,固然和ArrayList创建的Iterator是同一接口,然则,因为Vector是同步的,当一个Iterator被创建并且正在被应用,另一个线程改变了Vector的状况(例如,添加或删除了一些元素),这时调用Iterator的办法时将抛出ConcurrentModificationException,是以必须捕获该异常。

枚举Enumeration是Vector特有的取出方法

发现枚举和迭代器很像。

其实枚举和迭代是一样的

因为枚举的名称以及方法的名称都过长

所以被迭代器取代了。

代码示例:

import java.util.*;
class VectorDemo
{
public static void main(String[] args)
{
Vector nm=new Vector();
nm.add("hello 01");
nm.add("hello 02");
nm.add("hello 03");
nm.add("hello 04");
Enumeration v=nm.elements();
while(v.hasMoreElements())
{
System.out.println(v.nextElement());
}
}
}


七.ArrayList

 ArrayList实现了可变大小的数组。它允许所有元素,包括null。ArrayList没有同步(线程不安全)

 ArrayList应用操作示例:取出ArrayList集合中重复的元素

 

思路:定义一个临时容器ArrayList,使用迭代遍历原来集合中的元素是否在新容器中存在(contains())若不存在,则存入新容器

import java.util.*;
class ArrayListDemo
{
public static void main(String[] args)
{
ArrayList li=new ArrayList();
li.add("java01");
li.add("java02");
li.add("java03");
li.add("java04");
li.add("java02");
li.add("java04");
sop("li=  "+li);

sop("arraymethod(li)=  "+arraymethod(li));
}
public static Object/* ArrayList*/ arraymethod(ArrayList obj)
{

ArrayList s=new ArrayList();

for(Iterator in=obj.iterator();in.hasNext();)//使用完释放对象。
{
Object n=in.next();
if(!s.contains(n))
s.add(n);
}
return s;
}
public  static void sop(Object obj)
{
System.out.println(obj);
}
}


编译结果:



重点,

1.添加对象add(Object obj)被转型到Object,所以调用的时候要向下转型,转为调用对象类型Person

2.Iterator 的next 操作是对元素操作,对元素内部对象操作需要通过定义一个Person 的变量指向next();

3.判断元素内部对象是否相同不是判断元素相同

通过ArrayList里面contains,其实他是调用Object的equals方法。比较的是对象的地址值

代码如下:

import java.util.*;
class Person
{
private String name;
private int age;
Person(String name,int age)
{
this.age=age;
this.name=name;
}
public boolean equals(Object obj)
{
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;
}
public String getname()
{
return name;
}
public int getage()
{
return age;
}
}
class PersonDemo
{
public static void main(String[] args)
{
ArrayList a1=new ArrayList();
ArrayList a2=new ArrayList();
a1.add(new Person("张三",25));//**add(Object obj)里面添加的对象是Objcet类的
a1.add(new Person("李四",28));//**Object obj= newPerson("李四",28);
a1.add(new Person("李四",28));//此时a1提升为Object类型,向上转型。
a1.add(new Person("王二",34));
a1.add(new Person("王二",34));
a1.add(new Person("刘五",27));
sop(a1.remove(new Person("刘五",27)));
//a1=singleElement(a1);
Iterator ln=a1.iterator();
while(ln.hasNext())
{
Person p=(Person)ln.next();//**要向下转型为Person类才能操作
sop("姓名= "+p.getname()+"; 年龄= "+p.getage());//**ln是Object类的所以要向下转型为Person类型。
}
}
public static ArrayList singleElement(ArrayList a1)
{
//定义一个临时容器
ArrayList a2=new ArrayList();
Iterator it = a1.iterator();
while(it.hasNext())
{
Object obj=it.next();//转型为Object类型
if(!a2.contains(obj))
a2.add(obj);//add(Object obj)
}
return a2;
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}


编译结果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: