JAVA 类集

来源:互联网 发布:java躲避子弹素材 编辑:程序博客网 时间:2024/05/19 13:27

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

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

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

 List 和 Set 是Collection  接口的子接口

一对值的操作接口:Map

排序的操作接口:SortedMap、SortedSet

输出的接口:Iterator、ListIterator、Enumetation

队列:Queue


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


Collection 接口


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


Collection 接口定义:

public interface Collection<E>extends Iterable<E>


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


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

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


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


List 接口


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

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

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


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



新的子类:ArrayList


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

public class ArrayList<E>extends AbstractList<E>implements List<E>,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 stubList<String> alllist = new ArrayList<String>(); //为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 stubList<String> alllist = new ArrayList<String>();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 stubList<String> alllist = new ArrayList<String>();alllist.add("Hello");  //增加元素,Collection接口定义alllist.add("MSDL");   //增加元素,Collection接口定义alllist.add(0,"World"); //增加元素,List接口定义alllist.add(0,"Temp");  //增加元素,List接口定义for (int i=0;i<alllist.size();i++){  // 循环输出System.out.println(alllist.get(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 <String> alllist = new ArrayList<String>();        alllist.add("Hello");  //增加元素,Collection接口定义        alllist.add("MSDL");   //增加元素,Collection接口定义        Object obj[] = alllist.toArray();        for (int i=0;i<obj.length;i++){  // 循环输出            System.out.println(obj[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 stubCollection <String> alllist = new ArrayList<String>();alllist.add("Hello");  //增加元素,Collection接口定义alllist.add("MSDL");   //增加元素,Collection接口定义String obj[] = alllist.toArray(new String[]{});for (int i=0;i<obj.length;i++){  // 循环输出String str = obj[i];System.out.println(str); //输出内容}}}

集合的其他操作方法

判断元素是否存在

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 stubList<String> alllist = new ArrayList<String>(); //为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 stubList<String> alllist = new Vector<String>(); //为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区别点ArrayListVector1推出时间是在JDK1.2之后推出的,属于新的类是在JDK1.0时推出的,属于旧的操作类2操作ArrayList 采用异步的处理操作Vecotr采用同步的处理操作3性能ArrayList 性能高Vector 性能相对较低4安全非线程安全的操作线程安全5输出Iterator、ListIterator、foreachIterator、ListIterator、foreach、Enumeration


LinkedList 和 Queue 接口


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

此类定义如下:


public class LinkedList<E>extends AbstractSequentialList<E>implements List<E>,Deque<E>,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 stubLinkedList<String> link = new LinkedList<String>();link.add("A");link.add("B");link.add("C");link.addFirst("X");link.addLast("Y");System.out.println(link);for (int i = 0;i<link.size();i++){System.out.println(link.get(i));}}}


取出表头的操作


package org.collectiondemo.listdemo;import java.util.LinkedList;public class LinkedListDemo02 {/** * @param args */public static void main(String[] args) {// TODO Auto-generated method stubLinkedList<String> link = new LinkedList<String>();link.add("A");link.add("B");link.add("C");link.addFirst("X");link.addLast("Y");System.out.println(link);for (int i = 0;i<link.size();i++){System.out.print(link.element()); //取出表头}System.out.println(link);for (int i = 0;i<link.size();i++){System.out.print(link.poll()); //取出表头,同时删除表头}System.out.println(link);}}



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 stubSet<String> allSet = new HashSet<String>();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 stubSet<String> allSet = new TreeSet<String>();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<Person> {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;}@Overridepublic int compareTo(Person per) {// TODO Auto-generated method stubif (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 stubSet<Person> setp = new TreeSet<Person>();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方法类型描述1public boolean hasNext()普通将指针向下移动,判断是否还有内容2public E next()普通取出当前指针位置的内容3public void remove()普通删除当前指针位置的内容


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

public Iterator<T> 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 stubList<String> allList = new ArrayList<String>();allList.add("A");allList.add("A");allList.add("B");allList.add("C");allList.add("D");ListIterator<String> 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 stubList<String> allList = new ArrayList<String>();allList.add("A");allList.add("A");allList.add("B");allList.add("C");allList.add("D");ListIterator<String> 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 stubList<String> allList = new ArrayList<String>();allList.add("A");allList.add("A");allList.add("B");allList.add("C");allList.add("D");ListIterator<String> 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<E> listIterator()


此接口的操作方法如下:

No.方法类型描述1public void add(E e)普通增加数据2public boolean hasNext()普通从Iterator 继承而来3public E next()普通从Iterator 继承而来4public void remove()普通从Iterator 继承而来5public bollean hasPrevious()普通判断是否有前一个元素6public E previous()普通取出前一个元素7public 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 stubList<String> allList = new ArrayList<String>();allList.add("A");allList.add("A");allList.add("B");allList.add("C");allList.add("D");ListIterator<String> 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 stubList<String> allList = new ArrayList<String>();allList.add("A");allList.add("A");allList.add("B");allList.add("C");allList.add("D");ListIterator<String> 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 stubList<String> allList = new ArrayList<String>();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<E> 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 stubVector<String> allList = new Vector<String>();allList.add("A");allList.add("A");allList.add("B");allList.add("C");allList.add("D");Enumeration<String> enu = allList.elements();while(enu.hasMoreElements()){System.out.println(enu.nextElement());}}}


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

原创粉丝点击