【集合概述】【迭代器】【Vector中的枚举】【List集合】【LinkList】【ArrayList】



集合类Collection

集合是存储对象的容器,以便于对多个对象进行操作

集合与数组的区别

数组也可以存储对象,但是长度固定,集合的长度可变

数组还可以存储基本数据类型,集合只能存储对象

集合的特点:

只用于存储对象,且可以存储不同类型的对象,长度可变

集合框架

集合相关的API可以分为三类:接口(Interface)、实现类(Implementation)、抽象类(Abstract)

这些API统称为集合框架(Collection Framework),存放在jav.util包中,所以在使用时要导入java.util包

集合框架中存在多个容器,每一个容器对数据的存储方式都不同,这种存储方式称为:数据结构


v常用操作示例:

共性方法

import java.util.*;	//使用了包中的方法,要先导包
class  CollectionDemo
{
	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
	
	public static void main(String[] args) 
	{
		//base_method();
		//method_2();
		method_get();
	}
	public static void method_get()
	{
		ArrayList a1 = new ArrayList();
		a1.add("java1");			
		a1.add("java2");		
		a1.add("java3");
					//接口型引用,通过集合中的方法
		Iterator it = a1.iterator();//获取迭代器,用于取出集合中元素
		while (it.hasNext())//若果仍有元素可迭代返回真,false则跳出循环
		{
			sop(it.next());
		}
	}
	public static void method_2()//交集
	{
		ArrayList a1 = new ArrayList();
		a1.add("java1");			
		a1.add("java2");		
		a1.add("java3");

		ArrayList a2 = new ArrayList();
		a2.add("java1");			
		a2.add("java8");		
		a2.add("java6");

		//a1.retainAll(a2);	//取交集,a1中只保留和a2中相同的元素
		a1.removeAll(a2);	//去交集,a1中只保留和a2中不同的元素

		sop("a1="+a1);
		sop("a2="+a2);
	}
	public static void base_method()
	{
		ArrayList a = new ArrayList();//创建一个集合容器,使用Collection接口的子类ArrayList
		a.add("java1");			//1、添加元素
		a.add("java2");		//add(Object obj);多态性
		a.add("java3");
		
		sop(a);		//打印原集合
		sop("size="+a.size());	//2、获取元素个数
		
		//a.remove("java3");	//3、删除元素
		//a.clear();			//	 清空集合
								//4、判断元素
		sop("java3是否存在:"+a.contains("java3"));
		sop("集合是否为空 :"+a.isEmpty());
		sop(a);
	}
}
【小结】

1,add方法参数为Object,多态性,以便于接受任意类型对象
2,集合中存储的都是对象的引用()
3,集合可以直接打印


Iterator接口,迭代器

集合中取出元素的方式

元素的取出方式定义在集合内部(内部类),以便于直接访问集合元素

每一个容器的数据结构不同,所以取出的动作细节也不一样。但是都有共性内容判断hasNext()、取出.next();

向上抽取出来一个规则:Iterator;采用内部类的设计,通过一个对外提供的方法iterator();  获取集合对象


Collection

|——List:元素是有序的,可以重复,因为该集合体系有索引;常见的子类对象:

|————ArrayList:数据结构是数组结构;特点:查询速度很快,但是增删稍慢;线程不同步

|————LinkedList链表数据结构;特点:查询较慢,增删很快

|————Vector:    数组数据结构;线程同步;慢;被ArrayList替代了

——Set:元素是无序的,不能重复

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

——add(index,element);
——addAll(index,Collection);

——remove(index);

——set(index,element);

——get(index):
——subList(from,to);
——listIterator();
——int indexOf(obj):获取指定元素的位置。
——ListIterator listIterator();


List集合特有的迭代器。ListIterator是Iterator的子接口。
在迭代时,不可以通过集合对象的方法操作集合中的元素。因为会发生ConcurrentModificationException异常。
所以,在迭代器时,只能用迭代器的方法操作元素,可是Iterator方法是有限的,只能对元素进行判断,取出,删除的操作,
如果想要其他的操作如添加,修改等,就需要使用其子接口,ListIterator。该接口只能通过List集合的listIterator方法获取。

List集合共性方法

import java.util.*;
class  ListDemo
{
	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
	public static void main(String[] args) 
	{
		ArrayList a1 = new ArrayList();
		a1.add("java1");			
		a1.add("java2");		
		a1.add("java3");
		sop("原集合:"+a1);
		
		ListIterator li = a1.listIterator();//更加强大
		while (li.hasNext())
		{
			Object obj = li.next();
			if (obj.equals("java2"))
				//li.add("java007");//添加
				li.set("java008");	//修改
		}
		while (li.hasPrevious())	//如果前面有元素则返回true
		{
			sop("pre:"+li.previous());//反向获取
		}

/*		Iterator it = a1.iterator();	//迭代器,在迭代过程中,准备添加或删除元素
		while (it.hasNext())			//只能查,删,不能添加修改
		{
			Object obj = it.next();
			if (obj.equals("java2"))
				it.remove();	//集合中持有的只是对象的引用,删除的也只是引用
			sop("obj="+obj);	//remove后对象并没有删除,所以obj的指向时仍有效
		}*/
		sop(a1);
	}

	public static void method()
	{
		ArrayList a1 = new ArrayList();

		a1.add("java1");			
		a1.add("java2");		
		a1.add("java3");
		sop("原集合:"+a1);

		a1.add(2,"java08");	//在指定位置添加元素
		a1.remove(1);		//删除指定角标元素
		a1.set(2,"java007");//修改指定角标元素

		sop("get(1)"+a1.get(1));//通过角标获取元素
		sop(a1);
		
		for (int x =0; x<a1.size() ;x++ )//获取所有元素
		{
		//	sop("a1("+x+")="+a1.get(x));
		}

		Iterator it = a1.iterator();		//迭代器
		while (it.hasNext())
		{
			sop("next:"+it.next());
		}
		sop("index="+a1.indexOf("java007"));//通过indexOf获取对象的位置
		List sub = a1.subList(0,2);		//包含头不包含尾
		sop("sub="+sub);
	}
}

Vector中的枚举

elements

		Enumeration en = v.elements();
		while (en.hasMoreElements)
		{
			System.out.println(en.nextElement());
		}
//枚举就是Vector特有的取出方式,枚举和迭代是一样的,被迭代器取代
//因为枚举名称及方法的名称都过长,所以被迭代器取代了

LinkedList:特有方法
addFirst();
addLast();

getFirst();
getLast();

removeFirst();
removeLast();
如果列表为空,会抛出:NoSuchElementException

JDK1.6出现的替代方法

如果列表为空,会返回null
offerFirst();
offerLast();

peekFirst();
peekLast();

pollFirst();
pollLast();

LinkList操作

import java.util.*;
class LinkedListDemo 
{	
	public static void sop (Object obj)
	{
		System.out.println(obj);
	}
	public static void main(String[] args) 
	{		
		LinkedList link = new LinkedList();
		link.addFirst("java1");	
		link.addLast("java2");	//在上一个元素尾部添加
		link.addFirst("java3");	//在上一个元素头部添加
		link.addFirst("java4");
		
		sop(link);
		sop(link.getFirst());	//获取链表头部元素,不删除
		sop(link.getLast());	//获取链表尾部元素
		sop(link.removeFirst());//获取并删除元素,长度改变
		sop(link.removeFirst());//可以重复出现
		sop("size="+link.size());//获取链表长度
		
		while (!link.isEmpty())
		{
			sop(link.removeFirst());
		}
	}
}

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

堆栈:先进后出 杯子

队列:先进先出 水管

示例:

class DuiLie
{
	private LinkedList link;
	DuiLie()
	{
		link = new LinkedList();
	}
	public void myAdd(Object obj)
	{
		link.addFirst(obj);		//
	}
	public Object myGet()
	{
		//return link.removeLast();//先进先出
		return link.removeFirst();//后进先出
	}
	public boolean isNull()
	{
		return link.isEmpty();
	}
}

取出ArrayList集合中的重复元素

	public static ArrayList singleElement(ArrayList al)
	{
		ArrayList newAl = new ArrayList();//临时容器

		Iterator it = al.iterator();	//迭代数组al的元素
		while (it.hasNext())
		{
			Object obj = it.next();		
			if (!newAl.contains(obj))	//如果newAl中不包含该元素,则存入;如果重复则跳过
				newAl.add(obj);
		}
		return newAl;	//
	}

将自定义对象作为元素存储到ArrayList集合中,并去除重复元素
比如:人对象,同姓名同年龄就视为同一个人;作为重复元素
思路:
1,对人进行描述,封装对象
2,定义容器,将人存入

3,取出

ArrayList操作

import java.util.*;
class Person
{
	private String name;
	private int age;
	Person(String name,int age)
	{
		this.name = name;
		this.age = age;
	}
	public boolean equals(Object obj)//复写equals方法
	{
		if (!(obj instanceof Person))	//健壮性判断;一元运算符!要加括号
			return false;
		Person p = (Person)obj;		//类型向下强转
		return this.name.equals(p.name) && this.age==p.age;//字符串的equals方法
	}
	public String getName()
	{
		return name;
	}
	public int getAge()
	{
		return age;
	}
} 
class ArrayListTest2 
{	
	public static void sop(Object obj)
	{
		System.out.println(obj);
	}

	public static void main(String[] args) 
	{
		ArrayList al = new ArrayList();
		al.add(new Person("list001",23));//al.add(Object obj);多态性,不能直接访问子类Person特有方法
		al.add(new Person("list002",22));	//Object obj = new Person("list002",22);
		al.add(new Person("list003",25));
		al.add(new Person("list003",25));
		al.add(new Person("list004",27));
		al.add(new Person("list004",27));
		
		//al = singleElement(al);
		sop("remove 03:"+al.remove(new Person("list003",25)));//打印true说明在删除元素时要先equals判断是否存在

		Iterator it = al.iterator();
		while (it.hasNext())
		{
			Person p = (Person)it.next();	//必须向下转型	才能访问Person类的特有方法
			sop(p.getName()+"..."+p.getAge());
		}
	}

	public static ArrayList singleElement(ArrayList al)
	{
		ArrayList newAl = new ArrayList();//临时容器

		Iterator it = al.iterator();	//迭代数组al的元素
		while (it.hasNext())
		{
			Object obj = it.next();		
			if (!newAl.contains(obj))	//如果newAl中不包含该元素,则存入;如果重复则跳过
				newAl.add(obj);			//contains()调用的是equals方法
		}
		return newAl;	//
	}
}

【小结】

List元素判断元素是否相同,依据的是equals方法;ArrayList、LinkedList都是依赖于equals进行判断
contains()的判断调用了equals方法,默认调用的是Object的equals方法,每一个元素的调次数 是由临时容器中的元素个数决定的;
String类中复写了equals,所以在判断时函数自动覆盖,不需要再复写;字符串对象(以及基本数据类型对象)都在类中复写了equals
而用对象做比较时,如果该类没有复写equals方法,默认调用的是Object的equals;判断的是对象的地址值(即是否同一个对象);而如果判断的是对象的属性是否重复,所以要复写equals方法,使contains调用时默认重载

在remove()对象时,也会调用equals()方法,如果该对象的类中复写了equals(),调用时覆盖,打印出true(如示例所示)
如果该类中没有复写equals() 则打印出false,因为调用的是Object中的equals方法

要重视运算符的作用,灵活运用!

实际使用中ArrayList用的比较多,因为一般数据查询的操作比较多





posted on 2013-12-16 11:49  hwren  阅读(204)  评论(0编辑  收藏  举报

导航