Java 类集框架

来源:互联网 发布:新疆4g网络停用真相 编辑:程序博客网 时间:2024/05/19 09:12

http://blog.csdn.net/chai_daguanren/article/details/5111988


        在基础的应用中,我们可以通过数组来保存一组对象或者基本数据,但数组的大小是不可更改的,因此出于灵活性的考虑和对空间价值的担忧,我们可以使用链表来实现动态的数组。灵活的代价是操作上的繁琐,在计算机的世界,处理繁琐问题的不二法门就是将其封装,只向外暴露以供调用的方法视图。Java类集框架就是对这一方法的一种官方实现——一套动态对象数组的操作类,它其实就是Java对数据结构的一个大概的封装。在JDK1.5之后,这些接口都增加了泛型的定义,最早的时候这三个接口中的内容都使用Object进行操作。出于安全问题的考虑,以及避免转型之间的繁琐,JDK1.5将整个类集框架都升级为泛型。

三个核心接口
存放单值的最大父接口——Collection
public interface Collection<E> extends Iterable<E>
存放一对数据的最大接口——Map
public interface Map<K,V>
通用的输出接口——Iterator
public interface Iterator<E>


       按照面向对象的考虑,在使用单值集合时应以接口Collection来作为父类引用,但实践的结果是Collection的两个子接口List和Set获得了更多的青睐。
//1.添加一个元素public boolean add(E e);//2.清空集合public void clear();//3.是否包含特定元素public boolean contains(E e);//4.实例化Iterator遍历接口public Iterator<E> iterator();//5.从集合中删除特定的元素public boolean remove(Object o);//6.取得集合的大小public int size();//7.将集合转变为一个对象数组输出public Object[] toArray();//8.将集合转变为一个对象数组输出--泛型版本public <T> T[] toArray();




1  List        (Collection的一个子接口——允许重复且有序)的新增的主要方法视图:

//1.在指定的位置上添加一个元素public void add(int index, E element);//2.取得指定位置上的元素public E get(int index);//3.修改指定位置上的元素,返回原先的元素public E set(int index, E element);//4.为ListIterator接口实例化public ListIterator<E> listIterator();//5.删除指定位置上的元素,返回删除的那个元素的引用public E remove(int index);//ListIterator//它是Iterator接口的一个子接口,可以向前向后遍历List,而Iterator只能向后遍历。

1.1 子类:ArrayList
import java.util.ArrayList;import java.util.List;public class ArrayListDemo01 {public static void main(String[] args) {List<String> all = new ArrayList<String>(); // 实例化List接口all.add("hello"); // 向集合中增加内容all.add("world"); // 向集合中增加内容all.add("!!!"); // 向集合中增加内容for (int x = 0; x < all.size(); x++) {System.out.println(all.get(x)) ; }}}

1.2 子类:Vector

        Vector是最早的数据结构的实现类,也称为向量,在JDK1.0时并没有现在的类集框架的概念,它只是一个应需而生的操作类。在JDK1.2之后提出了类集框架,一系列专门设计的接口被推出,为了保留这个类,JDK1.2让它实现了List接口,完成类集的大一统。

       Stack表示的是栈的操作类,栈是一种典型的先进先出的设计,此类是Vector的子类。//入栈public E push(E item);//出栈public E pop();

 ArrayList和Vector的比较


       二者的操作接口基本一致,其区别是在内部的实现上:ArrayList在JDK1.2推出,比Vector晚,它采用异步处理的方式,而非Vector的同步方式,所以速度比较快,这也是它比较受欢迎的原因。相应的,ArrayList非线程安全,Vector则是线程安全的。二者都是List的实现类,都可以依靠size()和get()两个方法完成循环输出,都支持Iterator输出,不过Vector还支持Enumeration的输出方式,在实际运用中这种方式很少用到。

2  不允许重复的子接口:Set

         List接口中的内容是允许重复的,但是如果现在要求集合中的内容不能重复的话,就只能使用Set接口。Set接口不像List那样对Collection进行了大量的扩充,它对外的方法视图与Collection是完全一样的。

1)  散列存放的子类:HashSet

2)  排序存放的子类:TreeSet。

TreeSet中的元素对象可以排序要求它们实现Comparable接口,事先指定好排序规则。排序加入,compareTo()为0的对象元素将不会被再次添加。


3  Map接口
      Collection接口操作的时候每次都会向集合中添加一个元素,但是如果要添加的元素是一对的话,就要使用Map接口来完成了,其定义如下:

public interface Map<K,V>
//K表示键,V表示值

无序的存放: HashMap是Hashtable。

有序的存放:TreeMap.。但是需要注意的是既然按照key来排序,而key又是对象,所以就要求key实现Comparable接口。

HashMap是Hashtable的轻量级实现(非线程安全的实现),他们都完成了Map接口,主要区别在于HashMap允许空(null)键值(key),由于非线程安全,效率上可能高于Hashtable。
HashMap允许将null作为一个entry的key或者value,而Hashtable不允许。
HashMap把Hashtable的contains方法去掉了,改成containsvalue和containsKey。因为contains方法容易让人引起误解。 
Hashtable继承自Dictionary类,而HashMap是Java1.2引进的Map interface的一个实现。
最大的不同是,Hashtable的方法是Synchronize的,而HashMap不是,在多个线程访问Hashtable时,不需要自己为它的方法实现同步,而HashMap 就必须为之提供外同步。 
Hashtable和HashMap采用的hash/rehash算法都大概一样,所以性能不会有很大的差异。

HashMap和Hashtable的区别

No.               区别点                      HashMap                                         Hashtable
----------------------------------------------------------------------------------------------------
1.                 推出时间                   JDK1.2之后                                       JDK1.0

2.                 线程处理                   异步处理                                            同步处理

3.                 性能                         较快                                                   较慢

4.                 安全性                      非线程安全                                         线程安全

5.                 支持null                    允许key设置为null                             不允许key为null,否则会有


使用Iterator输出Map

public class MapPrint {public static void main(String[] args) {Map<String, String> all = new HashMap<String, String>();all.put("BJ", "BeiJing");all.put("NJ", "NanJing");all.put(null, "NULL");Set<Map.Entry<String, String>> set = all.entrySet();Iterator<Map.Entry<String, String>> iter = set.iterator();while (iter.hasNext()) {Map.Entry<String, String> me = iter.next();System.out.println(me.getKey() + " --> " + me.getValue());}}}


4 集合输出
在实际的应用中,只要是集合的输出基本上都不会采用将其变为对象数组的方式。遍历的方式有如下四种,它们的使用率是不一样的:
Iterator--95%
ListIterator--1%
Enumeration--4%
foreach--0%

迭代输出:Iterator

//判断是否有下一个元素public boolean hasNext();//取出当前的元素public E next();//删除当前的内容(不常用,造成错误,一般不用迭代器的,而是使用集合的 remove()方法)public void remove();

public class IteratorDemo {public static void main(String[] args) {List<String> all = new ArrayList<String>();all.add("hello");all.add("world");Iterator<String> iter = all.iterator();while (iter.hasNext()) { // 指针向下移动,判断是否有内容String str = iter.next();System.out.print(str + "、");}}}

双向迭代输出:ListIterator
Iterator接口完成的是从前往后的单向输出,如果要实现双向输出则要借助它的子接口:ListIterator

public class ListIteratorDemo {public static void main(String[] args) {List<String> all = new ArrayList<String>();all.add("hello");all.add("world");ListIterator<String> iter = all.listIterator();System.out.println("=========== 由前向后输出 ============");while (iter.hasNext()) {System.out.print(iter.next() + "、");}System.out.println("/n=========== 由后向前输出 ============");while (iter.hasPrevious()) {System.out.print(iter.previous() + "、");}}}