JAVA 类集

类集的概念是从JDK 1.2 之后正式完善的一套开发架构,其基本的作用就是完成了一个动态的对象数组,里面的数据元素可以动态的增加

类集提供了以下的几种接口:

单值操作接口:Collection、List、Set

 List 和 Set 是Collection  接口的子接口

一对值的操作接口:Map

排序的操作接口:SortedMap、SortedSet

输出的接口:Iterator、ListIterator、Enumetation

队列:Queue


所有的类集都保存在java.util包中,此包是一个最重要的工具包


Collection 接口


Collection 接口是一个最重要的操作接口,其中规定了一个集合的基本操作方法,此接口下有两个子接口,这两个子接口又分别有首各自的特点,在使用上完全不一样


Collection 接口定义:

public interface Collection

extends Iterable


在JDK1.5之后,Collection接口使用了泛型技术,那么这样做的目的可以保证接口中的操作的内容更加安全,因为最早来讲为了保证 Collection接口中可以增加任意的对象内容,所以使用了Object 进行接收,但是因为其可以接收任意的内容,所以在使用中就有可能在一个集合中插入不同的对象,在取出的时候就有可能出现类转换异常,所以在实际的类集操作中一定要指明其具体的操作泛型类型。


Coolection 接口中定义了如下的方法

No. 方法 类型 描述
1 public boolean add(E a) 普通 向集合中增加元素
2 public bollean addAll(Collectionc) 普通 向集合中加入一组数据,泛型指定了操作上限
3 public void clear() 普通 清空所有的内容
4 public boolean contains(Object 0) 普通 判断是否有指定的内容,查找
5 public boolean containsAll(Collectionc) 普通 查找一组数据是否存在
6 public boolean equals(Object o) 普通 对象比较
7 public in hashCode() 普通 返回hash 码
8 public bollean is Empty() 普通 判断集合的内容是否为空
9 public Iterator interator() 普通 为iterator 实例化,迭代输出
10 public boolean remove(Object o) 普通 从集合中删除指定的对象
11 public boolean removeAll(Collection c) 普通 从集合中删除一组对象
12 public boolean retainAll(Collection c) 普通 从集合中保留指定的对象
13 public int size() 普通 取得集合的长度
14 public Object[] toArray() 普通 取得全部的内容,以数据集合的形式返回
15 public T[] toArray(T[] a) 普通 取得全部的内容


从现化的开发中来看,在集合操作中已经很少去使用Collection 完成功能了,基本上都使用了其子接口:List、Set


List 接口


List 接口最大的特点是里面的内容都允许重复。但是,此接口比Collection 接口扩充了很多的方法

以下的方法是新增加的操作:

No. 方法 类型 描述
1 public void add(int index,E element) 普通 在指定的位置入加入元素
2 public bollean add All(int index x,Collection c) 普通 在指定位置增加一组元素
3 public E get(int index) 普通 通下索引位置可以取出每一个元素
4 public ListIterator listIterator() 普通 为ListIterator 接口实例化
5 public E remove(int index) 普通 删除指定位置内容
6 public E set(int index ,E element) 普通 修改指定位置内容
7 public List subList(int fromIndex,int toIndex) 普通 截取子集合


如果要想使用List 接口,则要通过其子类,常用的子类有如下几个:ArrayList、Vector、LinkedList



新的子类:ArrayList


ArrayList 是List 接口最常用的一个子类其定义如下:

public class ArrayList

extends AbstractList

implements List,RandomAccess,Cloneable,Serializable



使用ArrayList 的对象可以直接为List 接口实例化


完成增加数据的操作


package org.collectiondemo.listdemo;

import java.util.ArrayList;
import java.util.List;

public class ArrayListAddDemo {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		List alllist = new ArrayList(); //为List 接口实例化
		alllist.add("Hello");  //增加元素,Collection接口定义
		alllist.add("MSDL");   //增加元素,Collection接口定义
		alllist.add(0,"World"); //增加元素,List接口定义
		alllist.add(0,"Temp");  //增加元素,List接口定义
		System.out.println(alllist);
	}

}

通过代码运行可以发现此程序是没有数组长度限制的


完成删除数据的操作


package org.collectiondemo.listdemo;

import java.util.ArrayList;
import java.util.List;

public class ArrayListDeleteDemo {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		List alllist = new ArrayList();
		alllist.add("Hello");  //增加元素,Collection接口定义
		alllist.add("MSDL");   //增加元素,Collection接口定义
		alllist.add(0,"World"); //增加元素,List接口定义
		alllist.add(0,"Temp");  //增加元素,List接口定义
		alllist.remove("World"); //删除第一个位置的元素,List接口宝义
		alllist.remove(0);//删除第一个位置的元素,List 接口定义
		System.out.println(alllist);
	}

}



完成输出数据的操作

在List 接口中提供了一个get(int index) 方法,此方法可以根据索引位置取出数据


package org.collectiondemo.listdemo;

import java.util.ArrayList;
import java.util.List;

public class ArrayListPrintDemo {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		List alllist = new ArrayList();
		alllist.add("Hello");  //增加元素,Collection接口定义
		alllist.add("MSDL");   //增加元素,Collection接口定义
		alllist.add(0,"World"); //增加元素,List接口定义
		alllist.add(0,"Temp");  //增加元素,List接口定义
		for (int i=0;i


在Collection 接口中实际 上也规定了两个可以将集合变为对象数组的操作

package org.collectiondemo.listdemo;

import java.util.ArrayList;
import java.util.Collection;

public class ArrayListPrintDemo01 {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Collection  alllist = new ArrayList();
        alllist.add("Hello");  //增加元素,Collection接口定义
        alllist.add("MSDL");   //增加元素,Collection接口定义
        Object obj[] = alllist.toArray();
        for (int i=0;i


package org.collectiondemo.listdemo;

import java.util.ArrayList;
import java.util.Collection;

public class ArrayListPrintDemo02 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Collection  alllist = new ArrayList();
		alllist.add("Hello");  //增加元素,Collection接口定义
		alllist.add("MSDL");   //增加元素,Collection接口定义
		String obj[] = alllist.toArray(new String[]{});
		for (int i=0;i

集合的其他操作方法

判断元素是否存在

List 接口中定义的subList()方法


package org.collectiondemo.listdemo;

import java.util.ArrayList;
import java.util.List;

public class ArrayListOtherDemo {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		List alllist = new ArrayList(); //为List 接口实例化
		alllist.add("Hello");  //增加元素,Collection接口定义
		alllist.add("MSDL");   //增加元素,Collection接口定义
		alllist.add(0,"World"); //增加元素,List接口定义
		alllist.add(0,"Temp");  //增加元素,List接口定义
		System.out.println(alllist.contains("World"));
		System.out.println(alllist.subList(2, 3));
	}

}


旧的子类:Vector


Vector 类是一个元老级的操作类,在JDK1.0推出的时候就有了,ArrayList 类是在JDK1.2之后才定义的新操作类,但是因为考虑到一部份人已经习惯于使用Vector类,所以,Java的开发者在定义类集的时候又让Vector类多实现了一个List接口,所以此类可以直接为List接口实例化


package org.collectiondemo.listdemo;


import java.util.List;
import java.util.Vector;

public class VectorAddDemo {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		List alllist = new Vector(); //为List 接口实例化
		alllist.add("Hello");  //增加元素,Collection接口定义
		alllist.add("MSDL");   //增加元素,Collection接口定义
		alllist.add(0,"World"); //增加元素,List接口定义
		alllist.add(0,"Temp");  //增加元素,List接口定义
		System.out.println(alllist);
	}

}

当然,需要说明的是,在Vector类因为是一个比较老的类,所以里面也定义了自己的增加数据的操作,例如:public void addElement(E obj),那么现在此就去的操作跟List中是完全一样的。


ArrayList 与 Vector 的区别


ArrayList 类和Vector类都是List 接口的子类


No 区别点 ArrayList Vector
1 推出时间 是在JDK1.2之后推出的,属于新的类 是在JDK1.0时推出的,属于旧的操作类
2 操作 ArrayList 采用异步的处理操作 Vecotr采用同步的处理操作
3 性能 ArrayList 性能高 Vector 性能相对较低
4 安全 非线程安全的操作 线程安全
5 输出 Iterator、ListIterator、foreach Iterator、ListIterator、foreach、Enumeration


LinkedList 和 Queue 接口


LinedList 完成的是一个链表的操作,可以方便的找到表头之类的基本操作。

此类定义如下:


public class LinkedList

extends AbstractSequentialList

implements List,Deque,Cloneable,Serializable


此类提供的方法就是链表操作方法


package org.collectiondemo.listdemo;

import java.util.LinkedList;

public class LinkedDemo01 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		LinkedList link = new LinkedList();
		link.add("A");
		link.add("B");
		link.add("C");
		link.addFirst("X");
		link.addLast("Y");
		
		System.out.println(link);
		
		for (int i = 0;i


取出表头的操作


package org.collectiondemo.listdemo;

import java.util.LinkedList;

public class LinkedListDemo02 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		LinkedList link = new LinkedList();
		link.add("A");
		link.add("B");
		link.add("C");
		link.addFirst("X");
		link.addLast("Y");
		
		System.out.println(link);
		
		for (int i = 0;i



Set 接口


Set 接口也是Collection的子接口,最大的特点是里面没有任何的重复元素,在Set 接口中有以下的两个子类是最常用的子类

TreeSet :有序存放

HashSet: 散列存放

Set 接口本身并没有对Collection接口做任何的扩充,是安全一样


HashSet 散列存放


package org.collectiondemo.listdemo;

import java.util.HashSet;
import java.util.Set;

public class HashSetAddDemo {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Set allSet = new HashSet();
		allSet.add("A"); //增加重复元素
		allSet.add("A"); //增加重复元素
		allSet.add("B"); //增加
		allSet.add("C"); //增加
		allSet.add("D"); //增加重复元素
		allSet.add("D"); //增加重复元素
		System.out.println(allSet);
	}

}


TreeSet  有序存放


TreeSet 是可以进行排序的操作接口


package org.collectiondemo.listdemo;

import java.util.TreeSet;
import java.util.Set;

public class HashSetAddDemo {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Set allSet = new TreeSet();
		allSet.add("A"); //增加重复元素
		allSet.add("A"); //增加重复元素
		allSet.add("B"); //增加
		allSet.add("C"); //增加
		allSet.add("D"); //增加重复元素
		allSet.add("D"); //增加重复元素
		System.out.println(allSet);
	}

}


关于排序的说明


在之前的操作中使用的是String类的对象向集合中加入,如果现在自定义了一个类


package org.collectiondemo.listdemo;

public class Person implements Comparable {

	private String name;
	private int age;
	
	public Person(String name,int age){
		this.name = name;
		this.age = age;
	}
	
	public String toString(){
		return "姓名:"+this.name+" 年龄:"+this.age;
	}

	public boolean equals(Object obj){
		if (this == obj){
			return true;
		}
		
		if (!(obj instanceof Person)){
			return false;
		}
		
		Person per = (Person)obj;
		
		if (this.name.equals(per.name) && this.age == per.age){
			return true;
		}else{
			return false;
		}
	}
	
	public int hashCode(){ //这个方法的返回值都是通过一个公式计算的
                // 此时的公式:名字的hashCode * age
                return this.name.hashCode() * this.age;
	}

	@Override
	public int compareTo(Person per) {
		// TODO Auto-generated method stub
		if (this.age < per.age){
			return -1;
		}else if (this.age > per.age){
			return 1;
		}else{
			return this.name.compareTo(per.name); //比较name
		}
			
	}
}

package org.collectiondemo.listdemo;
import java.util.Set;
import java.util.TreeSet;



public class TreeSetPersonDemo {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Set setp = new TreeSet();
		setp.add(new Person("张三",20));
		setp.add(new Person("李四",20));
		setp.add(new Person("王五",20));
		setp.add(new Person("赵六",20));
		setp.add(new Person("孙七",20));
		setp.add(new Person("孙七",20));
		System.out.println(setp);
	}

}

关于重复元素的说明


如果将以上的程序替换成HashSet子类,则会发现存在了重复元素,那么现在覆写equals()方法。

而且如果要想完成对象重复元素的判断,还需要覆写Object类中的hashCode()方法


在程序中是通过Object 类中的hashCode()和euqals()方法来完成重复元素的验证

所以,一个完整的类必须覆写Object 类中的hashCode()和equals()方法就在这里。


集合输出


在Java 的类集中集合输出有以下四种方式:

Iterator

ListIterator

foreach

Enumeration

但是在讲解之前先给一个标准的开发模式:“只要是碰到集合的输出,使用Iterator 接口”


Iterator


Iterator 表示迭代接口。Iterator 接口中定义了如下的方法


No 方法 类型 描述
1 public boolean hasNext() 普通 将指针向下移动,判断是否还有内容
2 public E next() 普通 取出当前指针位置的内容
3 public void remove() 普通 删除当前指针位置的内容


如果要想为Iterator 接口实例化,则必须使用Collection接口的如下方法:

public Iterator iterator()

通过以下代码观察Iterator 的使用


package org.iteratordemo;

import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;

public class ListIteratorDemo01 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		List allList = new ArrayList();
		allList.add("A");
		allList.add("A");
		allList.add("B");
		allList.add("C");
		allList.add("D");
		ListIterator listiter = allList.listIterator();
		
		while (listiter.hasNext()){
			System.out.println(listiter.next());
		}
		
		System.out.println(allList);
	}

}

但是在Iterator 接口中存在一个删除的方法,在使用此方法的时候一定要有注意


正确的删除:


package org.iteratordemo;

import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;

public class ListIteratorDemo03 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		List allList = new ArrayList();
		allList.add("A");
		allList.add("A");
		allList.add("B");
		allList.add("C");
		allList.add("D");
		ListIterator listiter = allList.listIterator();
		listiter.add("E");
		
		
		while (listiter.hasNext()){
			String str = listiter.next(); //取出内容
			if ("D".equals(str)){
				listiter.remove(); //删除元素,使用的是List 接口的删除
			}
			System.out.print(str+"、");
		}
		
		System.out.println("");
		
		while (listiter.hasPrevious()){
			System.out.print(listiter.previous()+"、");
		}
		

	}

}

不正确的删除操作:


package org.iteratordemo;

import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;

public class ListIteratorDemo03 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		List allList = new ArrayList();
		allList.add("A");
		allList.add("A");
		allList.add("B");
		allList.add("C");
		allList.add("D");
		ListIterator listiter = allList.listIterator();
		listiter.add("E");
		
		
		while (listiter.hasNext()){
			String str = listiter.next();
			if ("D".equals(str)){
				allList.remove(str);
			}
			System.out.print(str+"、");
		}
		
		System.out.println("");
		
		while (listiter.hasPrevious()){
			System.out.print(listiter.previous()+"、");
		}
		

	}

}


因为所谓的Iterator 实际上,只是将一个集合的内容交给了Iterator 输出而已,而如果直接使用了集合中的remove()方法,删除的话,则会存坏整个集合的内容,所以输出的时候会出现问题。

而在实际的开发中是很少使用Iterator 进行删除的操作,只是判断是否有值并且将值输出


ListIterator


ListIterator 是Iterator 接口的子接口。Iterator接口的最大特点,是能从前向后迭代输出,如果现在要想执行双向的输出,则只能使用ListIterator 接口,但是此接口使用时有一个要求,即:只能输出List接口的内容,因为要依靠如下的方法 


public ListIterator listIterator()


此接口的操作方法如下:

No. 方法 类型 描述
1 public void add(E e) 普通 增加数据
2 public boolean hasNext() 普通 从Iterator 继承而来
3 public E next() 普通 从Iterator 继承而来
4 public void remove() 普通 从Iterator 继承而来
5 public bollean hasPrevious() 普通 判断是否有前一个元素
6 public E previous() 普通 取出前一个元素
7 public void set(E e) 普通 修改元素内容


下面就使用ListIterator 接口进行双向的输出操作


package org.iteratordemo;

import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;

public class ListIteratorDemo02 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		List allList = new ArrayList();
		allList.add("A");
		allList.add("A");
		allList.add("B");
		allList.add("C");
		allList.add("D");
		ListIterator listiter = allList.listIterator();
		System.out.print("从前向后输出:");
 while (listiter.hasNext()){System.out.print(listiter.next()+"、");}System.out.println("\n从后向后输出:");while (listiter.hasPrevious()){System.out.print(listiter.previous()+"、");}System.out.println(allList);}}
 
  


在使用Listerator 接口的时候还有一个特别大的特点,可以增加及修改数据


package org.iteratordemo;

import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;

public class ListIteratorDemo03 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		List allList = new ArrayList();
		allList.add("A");
		allList.add("A");
		allList.add("B");
		allList.add("C");
		allList.add("D");
		ListIterator listiter = allList.listIterator();
		listiter.add("E"); //增加数据
		
		
		while (listiter.hasNext()){
			String str = listiter.next();

			listiter.set(str + "-- MSDL"); //修改数据
			System.out.print(str+"、");
		}
		
		System.out.println("");
		
		while (listiter.hasPrevious()){
			System.out.print(listiter.previous()+"、");
		}
		

	}

}

foreach


在数组的输出上可以使用foreach 完成,那么对于集合也同样适用


package org.iteratordemo;

import java.util.ArrayList;
import java.util.List;

public class ForeachDemo {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		List allList = new ArrayList();
		allList.add("A");
		allList.add("A");
		allList.add("B");
		allList.add("C");
		allList.add("D");
		for (String str : allList){
			System.out.println(str);
		}
	}

}

废弃的接口:Enumeration


Enumeration 是一个古老的输出接口,支持此种输出的类只有Vector类

在Vector类中存在以下的方法:public Enumeration elements(),通过此方法为Enumeration 接口进行实例化的操作

Enumeration 接口定义了如下的方法:

判断是否还有内容:boolean hasMoreElements()

取出内容:E nextElement()

可以发现此接口定义的方法功能与Iterator类似,而且单词比 Iterator 长很多,所以记得费劲,所以基本上不使用


package org.iteratordemo;

import java.util.Enumeration;
import java.util.Vector;

public class EnumerationDemo {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Vector allList = new Vector();
		allList.add("A");
		allList.add("A");
		allList.add("B");
		allList.add("C");
		allList.add("D");
		Enumeration enu = allList.elements();
		while(enu.hasMoreElements()){
			System.out.println(enu.nextElement());
		}
	}

}


当然,对于一些旧的操作类中现在依然支持Eumeration ,这一点在日后的Java Web 的开发中可以见到。所以掌握此接口也是很有必要的。

你可能感兴趣的:(JAVA 类集)