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

黑马程序员 java集合—泛型

2012-01-05 14:28 381 查看
---------------------- android培训java培训、期待与您交流! ----------------------

ListsetMapIterator概述

ArrayList是可变容量数组,它的特性和数组很接近;
LinkedList是数据结构中的链表,在其中增加、删除元素效率高;
Vector是传统的集合实现,已不再推荐使用,其实现在可以用
ArrayList、LinkedList来代替;Stack是数据结构中栈的Java实现,一种后进先出的数据结构,因为它采用Vector来实现,所以也不推荐使用,它的功能可以使用其他集合来代替。
HashSet是数据散列Set,而TreeSet则是一种排序的Set实现。
HashMap是最普通的Map实现,其中的元素成散列存取;TreeMap是排序Map;HashTable是传统的Java实现,现在也已经不推荐使用,它的实现被HashMap替代。

Iterator接口与Collection的关系也非常密切,并且特殊。
– Iterator对象由Collection接口对象产生,ListIterator对象则是由List接口对象产生的。
– Collection接口对象包含Collection子接口的所有实现,也就是说,Collection的所有子接口对象都可以产生Iterator对象。
Iterator(迭代器):
– 集合是存放一组元素的,元素的存入和取出必然需要集合的实现类提供方法来支持,而不同的实现类提供的方法可能不同。
– 如果我们把“对集合内元素的访问”和“实现采用的集合”分离开:从集合的实现中取得Iterator接口对象,然后通过Iterator对象来遍历集合,然后再采用Iterator接口的通用方法在集合中访问每一个元素。
– 这种通用的对于集合遍历的实现就是Iterator接口。
因为通用性的原因,Iterator的功能比较简单,使用中只能单向移动。它提供的通用方法有:
– 集合对象.iterator():返回集合对象的Iterator接口对象;
Iterator对象.next():从集合中取得下一个元素,返回的是Object类型;
Iterator对象.hasNext():检查集合中是否还有下一个元素,返回boolean类型;
Iterator对象.remove():从集合中删除最近获得的对象元素。
Iterator是为遍历而设计,能够从集合中取出元素和删除元素,但是没有添加元素的功能。集合遍历元素的顺序就是集合中元素存储的顺序。

List 是有一定顺序的元素集合。我们可以通过集合的索引值(相当于数组的元素下标,也就是元素在List中的位置)来访问元素以及在集合中进行查询。
List与Set的一个区别是:List中的元素可以重复,元素是有顺序的;而Set的元素不能重复,并且其中的元素是无序的。

我们如何使用它呢?利用List或是Collection声明集合对象,然后该对象指向一个List的实现集合类(如ArrayList、LinkedList),取出元素时一般采用Iterator接口提供的方法,当然也可以使用 Object get(int index)方法。
List相对于Collection的主要增强功能有两点:
– 因为List元素的有序性,所以每个元素都有index值,与该索引相关的增加了一些方法:添加、删除元素都可以在指定的位置进行。
– 可以通过List取得ListIterator来访问List,ListIterator接口是Iterator接口的子类,它增强的地方是Iterator只能单向遍历,而ListIterator则可双向遍历(向前或是向后);另外,ListIterator有增加元素的功能(Iterator则无此功能)。
对比:
ArrayList是线性顺序存储 , LinkedList对象间彼此串连起来的一个链表。
ArrayList适合随机查询的场合 , LinkedList元素的插入和删除操作效率高。
从功能上,LinkedList要多一些。
Vector是线程安全的,而ArrayList是线程不安全的。Vector虽然线程安全,但性能上影响较大 ,一般多采用ArrayList。
List的使用:
使用Collection或是各个实现类的上层接口来声明集合对象,有个好处是,以后想更改集合的实现时,可以仅仅在此处(集合对象的定义处)修改该集合对象的实现。
– 如原来是用ArrayList实现的,可以直接修改为LinkedList等(只要该实现是Collection或是List的子类就可以)。而且在以后使用集合的时候采用标准的Iterator接口,所以遍历的方法部分不需要做任何修改。
注意区分ArrayList、LinkedList各自的特性:
– ArrayList是线性顺序存储的,是一种线性表,适合元素的随机存取访问;而LinkedList不是顺序存储的,是对象间彼此串连起来的一个链表;
– ArrayList适合随机查询的场合,按照索引值取元素、设置元素等操作性能高,但是插入元素和删除元素的性能比较差,尤其在集合中间加入和删除元素操作。LinkedList元素的插入和删除操作性能高,但不适合随机查询;
– 从功能上LinkedList要多些,提供了从头部尾部插入、删除、取得元素的方法,所以常用LinkedList来实现队列、堆栈等数据结构。

LinkedList的使用:是数据结构中链表的java实现,元素在LinkedList中的存储是一个元素接着一个元素串连起来,通过每个元素维护它的前驱和后续节点的连接。它的线性化特征已经很弱了,因为它不需要顺序存储。在该集合中添加和删除元素方面,性能要好得多。

相对于List来说,它最主要的功能方面的增强是可以在List的头部和尾部添加、删除、取得元素,直接提供了这些方法的实现。所以它可以非常方便的实现我们数据结构中的常见的Stack()queue(队列)等。
LinkedList的增强功能:
void addFirst(Object o) void addLast(Object o) Object getFirst() Object getLast()
Object removeFirst() Object removeLast()

Set接口是Collection接口的另外一个子接口。与List的一个主要区别是Set集合内存放的元素不允许重复,且是唯一值。而且向Set集合内存入的元素不是按照原来的顺序存储的。(我们成为它“无序”)。
那么对象不重复在java中的含义是什么呢?两个对象e1和e2,如果e1.equals(e2)返回true,则认为e1和e2重复;允许在set中保存NULL值,只允许保存一次。
默认两个对象是否相等的equals方法是判断两个对象的对象变量引用值是否指向同一个地址空间,但是如果我们重写了对象类的equals方法,则依据我们自己的equals方法进行用户自定义相等的比较。
Set有两种主要的集合实现:HashSet、TreeSet;
HashSet的特性在于其内部对象的散列存取,即采用哈希技术,每个对象利用hashCode()方法算出一个唯一hash值,然后根据该hash值把各个对象尽可能均匀分部到集合中去。当读取对象的时候,同样先计算出对象的hash值,然后根据该值快速到集合中
的对应位置取出对象元素。
Set的特性在于集合中的元素的无序,这个无序,是指元素存入顺序和集合内存储的顺序不同。TreeSet虽然存入的顺序跟存储的顺序不同,但是存储是按照排序存储的。
import java.util.*;
public class SetExample {
public static void main(String[] args) {
Set set = new HashSet();
set.add("one"); set.add("second"); set.add("3rd") ;set.add(new Integer(4))
;set.add(new Float(5.0F)); set.add("second"); set.add(new Integer(4));
System.out.println(set);
}
}

Map是不同于Collection的另外一种集合接口。
Map内存储的是键/值(key/value)对这样成对的对象组(可以把一组对象当成一个元素),通过“键”对象来查询“值”对象。这个概念类似数据库中表的查询,表经常会设置主键,主键值对于每一条记录来说是唯一的,所以只要能过快速找到主键,就可以快速定位一条记录,从而取出那条记录。
在Map中,key值也是唯一的,我们通过一些方法快速找到key值(key对象),而key对象是与value对象关联在一起的,找到了key对象,自然也快速定位到value对象,从而快速取出value对象。
Map接口有两个实现,HashMap和TreeMap
HashMap中key /value对的存放和查询是采用hash算法,每个key对象都对应唯一的一个hash值,根据该hash值,可以快速定位key对象,进而定位到value对象(因为是成对出现)。当在插入元素的时候,如果key已经存在,则替换原来的value对象。
TreeMap中key/value对是排序的(按照key排序)存储的。
import java.util.HashMap;
public class MapExample {
public static void main(String[] args) {
HashMap map1 = new HashMap();
map1.put("li", new String("li-si age=10"));
map1.put("zhang", new String("zhang-san age=20"));
map1.put("wang", new String("wang-wu age=30"));
String valueTmp = (String) map1.get("zhang");
System.out.println("zhang's result is " + valueTmp);
}
}
区别:
HashMap中key/value对的存放和查询是采用Hash算法 。TreeMap中键/值对是排序(按照key排序)存储的。HashTable是线程安全的,而HashMap不是线程安全的。从性能角度考虑,HashMap要比HashTable要好。
如何选择集合类:
Set内存放的元素不允许重复,List存放的元素有一定的顺序。Map的应用主要在利用键/值对进行快速查询。ArrayList和LinkedList的区别在于随机查询性能上ArrayList
要好,但LinkedList的中间元素的插入与删除性能好。
HashSet和TreeSet的区别在于集合内元素是否排序。

泛型经常被称为参数化类型,它能够像方法一样接受不同类型的参数。定义方式为<>
ArrayList<E> myArrayList ;
泛型会产生出一个新的数据类型,那么这个新的数据类型就可以作为类型参数来使用,创建出一个新的泛型。
import java.util.*;

class GenericVarTest {

public static void main(String[] args) {

ArrayList<String> str = new ArrayList<String>();

str.add("aaaa");

str.add("bbbb");

ArrayList<String> str1 = new ArrayList<String>();

str1.add("cccc");

str1.add("dddd");

ArrayList<ArrayList<String>> listofStr=new

ArrayList<ArrayList<String>>();//泛型作为参数产生一个新的泛型类

listofStr.add(str);listofStr.add(str1);

String s = listofStr.get(0).get(0);

System.out.println(s); //prints"bbbb“

String s1 = listofStr.get(1).get(0);

System.out.println(s1); //prints"cccc"
}
}
泛型中可以使用“?”通配符作为参数,表示该泛型可以接收任意类型的数据。
上界通配符:泛型中只允许一个类自身(接口)或者其子类(实现该接口的类)作为参数传入。
– 表示方式为:泛型类型<? extends 父类(接口)>
下界通配符:表示泛型中只允许一个类自身或者该类的父类作为参数传入。(很少使用)
– 表示方式为:泛型类型<? super 子类>。
创建泛型和定义一个类一样,只要类型变量位于类后面的<>中就可以。
class Point<E> {E x;E y;

public Point(E x1, E y1) {x = x1;y = y1;}

public E getX() {return x;}

public E getY() {return y;}

public void setX(E x1) {x = x1;}

public void setY(E y1) {y = y1;}

}

---------------------- android培训java培训、期待与您交流! ----------------------
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: