黑马程序员 java集合—泛型

---------------------- 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培训、期待与您交流! ----------------------

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值