java-集合与泛型

集合

我们首先介绍一下集合的概念

 

集合:集合是java中提供的一种容器,可以用来存储多个数据。

那么它和数组有什么不同呢?

 

数组的长度是固定的,集合的长度是可变的。

数组中存储的是同一类型的元素,可以存储基本数据类型值。集合存储的都是对象,而且对象的类型可以不一致。

所有的集合框架都包含如下内容:

 

接口:是代表集合的抽象数据类型,例如:Collection、List、Set、Map等。之所以定义多个接口,是为了以不同的方式操作集合对象。

 

实现(类):是集合接口的具体实现,从本质上讲,它们是可重复使用的数据结构,例如:ArrayList,LinkedList,HashSet,HashMap.

 

算法:是实现集合接口的对象里的方法执行的一些有用的计算,例如搜索和排序,这些算法被称为多态,呢是因为相同的方法可以在相似的接口上有着不同的实现,

在这里插入图片描述

 

在上图中,实线边框的是实现类,虚线边框的是抽象类,点线边框的是接口。加粗的是比较常用的实现类。

 

从上图的集合框架,我们可以看到,java的集合框架主要包含两种类型的容器,一种是集合(Collection),存储一个元素集合,另一种是图(Map),存储键值对映射。Collection接口又有三种子类型,List,Set和Queue,再下面是一些抽象类,然后是具体实现类,常用的有ArrayList,LinkedList,HashSet,LinkedHashSet等等。

 

我们首先介绍一下Collection集合:

 

Collection:单列集合,用于存储一系列符合某种规则的元素,它有两个重要的子接口,分别是java.util.List和java.util.Set,其中,List的特点是元素有序、元素可重复。Set的特点是元素无序,而且不可重复。

Collection是所有单列集合的父接口。因此在Collection中定义了单列集合的一些方法

 

public boolean add(E e):把给定的对象添加到当前集合中。

public void clear():清空集合中所有的元素

public boolean remove(E e):把给定的对象在当前集合中删除。

public boolean contains(E e): 判断当前集合中是否包含给定的对象

public boolean isEmpty(): 判断当前集合是否为空

public int size(): 返回集合中元素的个数。

@Test

public void test2(){

    Collection<String> coll = new ArrayList<String>();

    coll.add("a");

    coll.add("b");

    coll.add("c");

    coll.add("e");

    coll.add("e");

    System.out.println(coll);//元素有序 且可重复

    coll.remove("a");

    System.out.println(coll);

    System.out.println(coll.contains("a"));

    System.out.println("集合中元素个数为:" + coll.size());

    coll.clear();//清空集合

    System.out.println("集合中内容为:" + coll);

    System.out.println(coll.isEmpty());

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

在这里插入图片描述

 

Iterator迭代器

在java中,为了遍历集合中存储的所有元素,JDK提供了一个接口java.util.Iterator.Iterator,它也是java集合中的一员,主要用于迭代访问(遍历),因此Iterator对象也被称为迭代器。

 

public Iterator iterator(): 获取集合对应的迭代器 用来遍历集合中的元素。

 

迭代: 即Collection集合元素的通用获取方式。在取元素之前先要判断集合中有没有元素,如果有,就把这个元素取出来,在继续判断,一直把集合中的所有元素全部取出。这种取出方式专业术语称为迭代

 

Iterator接口的常用方法如下:

 

public E next(): 返回迭代的下一个元素

public boolean hasNext(): 如果仍有元素可以迭代,则返回true;

 @Test

    public void test3(){

        Collection<String> coll = new ArrayList<String>();

        coll.add("a");

        coll.add("b");

        coll.add("c");

        Iterator<String> it = coll.iterator();

        while (it.hasNext()){

            System.out.println(it.next());

        }

    }

1

2

3

4

5

6

7

8

9

10

11

在这里插入图片描述

 

泛型

我们知道集合里面是可以存入任意对象的,只要把对象存储集合后,它们都会被提升成Ojbect类型,当我们在取出每一个对象,并且进行相应的操作,这时必须采用类型转换。

 

@Test

    public void test3(){

        Collection coll = new ArrayList();

        coll.add("a");

        coll.add("b");

        //coll.add("c");

        coll.add(5);

        Iterator<String> it = coll.iterator();

        while (it.hasNext()){

            String str = (String)it.next();

            System.out.println(str);

        }

    }

1

2

3

4

5

6

7

8

9

10

11

12

13

在这里插入图片描述

我们发现如果存储各种类型的数据,在取出时进行强转可能会引起java.lang.ClassCastException异常。

 

所以虽然Collection原则上可以存储各种对象,但实际上只存储同一类型对象,因此在JDK 5之后新增了泛型语法。

 

泛型: 可以在类或者方法中预支地使用未知的类型。

使用泛型的好处:

 

将运行时期的异常转到编译时期

避免了强制类型转换的麻烦。

定义和使用含有泛型的类

定义 格式:

 

修饰符 class 类名<代表泛型的变量> { }

 

例如, API中的ArrayList集合:

 

class ArrayList {

 

​ public boolean add(E e){

 

​ // 代码

 

​ }

 

​ public E get(int index){

 

​ }

 

}

 

使用泛型:即什么时候确定泛型

 

例如, ArrayList list = new ArrayList();

 

此时 变量E的值就是String类型,那么我们的类型就可以理解为:

 

class ArrayList{

 

​ public boolean add(String e){}

 

​ public String get(int index){}

 

}

 

通过使用泛型我们就不用为每一种类型的数据写一个方法了。

 

泛型通配符

当使用泛型类或者接口时,传递的数据中,泛型类型不确定,可以通过通配符<?>表示,但是一旦使用泛型的通配符后,只能使用Object类中的共性方法,集合中元素自身方法无法使用

 

例如你现在有个需求: 方法接受一个集合数据,然后要遍历集合并且把集合中的元素打印出来。

 

public void test(List<?> list){

     for(int i = 0; i < list.size(); i++){

          System.out.pritnln(list.get(i));

     }

}

1

2

3

4

5

这个时候我们不知道集合中元素的具体类型,只能使用<?>。?号通配符表示可以匹配任意类型,任意的java类都可以匹配。

 

因为泛型中的Object是没有继承关系的,也就是说List和List是毫无关系的。还有一点是当我们使用?号通配符的时候,就只能调用对象与类型无关的方法,不能调用对象与类型有关的方法。因为我们不知道具体的类型时什么。比如我们在上面的list集合里,是不能使用add()方法的,因为add()方法是把对象丢进集合中,而现在不知道类型是什么。

 

受限通配符

假设我们现在的List集合规定只能操作数字类型的元素例如Float,Integer,Double等类型。

 

这个时候如果我们还使用?通配符,该集合就不是只能操作数字了,因此,我们需要用到设定通配符上限和下限。

 

泛型的上限:

 

格式 : 类型名称<? extends 类> 对象名称

意义: 只能接受该类型及其子类

泛型的下限:

 

格式:类型名称<? super 类> 对象名称

意义: 只能接受该类型及其父类

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值