Collection、泛型

文章内容输出来源:拉勾教育大数据开发高薪训练营 

一、集合的基本概念

    当需要在Java程序中记录单个数据内容时,则声明一个变量。

    当需要在Java程序中记录多个类型相同的数据内容时,声明一个一维数组。

    当需要在Java程序中记录多个类型不同的数据内容时,则创建一个对象。

    当需要在Java程序中记录多个类型相同的对象数据时,创建一个对象数组。

    当需要在Java程序中记录多个类型不同的对象数据时,则准备一个集合。


二、单列集合的体系结构


三、Collection集合

        java.util.Collection接口是List接口、Queue 接口以及Set接口的父接口,因此该接口里定义的方法既可用于操作List集合,也可用于操作Queue集合和Set集合。

常用方法
方法声明功能介绍
public boolean add(E e);把给定的对象添加到当前集合中
public void clear();清空集合中所有的元素
public boolean remove(Object o);
把给定的对象在当前集合中删除
public boolean contains(Object o);
判断是否包含指定对象
public int size();
返回包含对象的个数
public boolean isEmpty()
判断是否为空
public Object[] toArray()
将集合转换为数组

四、Iterator接口(迭代器)

       java.util.Iterator接口主要用于描述迭代器对象,可以遍历Collection集合中的所有元素。

       java.util.Collection接口继承Iterator接口,因此所有实现Collection接口的实现类都可以使用该迭代器对象。

常用方法
方法声明功能介绍
boolean hasNext()
判断集合中是否有可以迭代 / 访问的元素
E next()
用于取出一个元素指向下一个元素
void remove()
用于删除访问到的最后一个元素

迭代器的实现原理:

       在调用Iterator的next方法之前,迭代器的索引位于第一个元素之前,不指向任何元素,当第一次调用迭代器的next方法后,迭代器的索引会向后移动一位,指向第一个元素并将该元素返回,当再次调用next方法时,迭代器的索引会指向第二个元素并将该元素返回,依此类推,直到hasNext方法返回false,表示到达了集合的末尾,终止对元素的遍历。  


五、for each循环

    可以应用数组和集合的遍历,简化版的迭代器;

    格式:for (元素类型 变量名 : 数组/集合名) { ... }


六、泛型

 6.1 基本概念:

通常情况下集合中可以存放不同类型的对象,是因为将所有对象都看做Object类型放入的,因此从集合中取出元素时也是Object类 型,为了表达该元素真实的数据类型,则需要强制类型转换,而强制类型转换可能会引发类型转换异常。

为了避免上述错误的发生,从Java5开始增加泛型机制,也就是在集合名称的右侧使用<数据类型>的方式来明确要求该集合中可以存放的元素类型,若放入其它类型的元素则编译报错。

6.2 使用泛型的好处:

a. 将运行时期的ClassCastException,转移到了编译时期变成了编译失败;

b. 避免了类型强转的麻烦。

6.3 泛型的底层原理:

泛型的本质就是参数化类型,也就是让数据类型作为参数传递,其中E相当于形式参数负责占位,而使用集合时<>中的数据类型相当于实际参数,用于给形式参数E进行初始化,从而使得集合中所有的E被实际参数替换,由于实际参数可以传递各种各样广泛的数据类型,因此得名为泛型。

      具体如下: 

6.4 自定义泛型类:

泛型类和普通类的区别就是类名后面添加了类型参数列表,可以有多个类型参数,如:<E, T, .. >;

实例化泛型类时应该指定具体的数据类型,并且是引用数据类型而不是基本数据类型。

父类有泛型,子类可以选择保留泛型也可以选择指定泛型类型。

子类必须是富二代,子类除了指定或保留父类的泛型,还可以增加自己的泛型。

泛型中的继承:如果BA的一个子类或子接口,而G是具有泛型声明的类或接口,则G并不是G的子类型!

比如:StringObject的子类,但是List<Integer>并不是List<Integer>的子类。

6.5 自定义泛型方法:

泛型方法就是我们输入参数的时候,输入的是泛型参数,而不是具体的参数。我们在调用这个泛型方法的时需要对泛型参数进行实例化。

格式:修饰符 <代表泛型的变量> 返回值类型 方法名(参数){  }

在静态方法中使用泛型参数的时候,需要我们把静态方法定义为泛型方法。

具体如下:

// 定义泛型方法
public class MyGenericMethod {	  
    public <MVP> void show(MVP mvp) {
    	System.out.println(mvp.getClass());
    }
    
    public <MVP> MVP show2(MVP mvp) {	
    	return mvp;
    }
}

// 调用泛型方法,在调用方法时,确定泛型的类型
public class GenericMethodDemo {
    public static void main(String[] args) {
        // 创建对象
        MyGenericMethod mm = new MyGenericMethod();
        // 演示看方法提示
        mm.show("aaa");
        mm.show(123);
        mm.show(12.45);
    }
}

6.6 定义泛型接口:

格式:修饰符 interface 接口名 <代表泛型的变量> {  }

如:

// 泛型接口
public interface MyGenericInterface<E>{
	public abstract void add(E e);
	
	public abstract E getE();  
}

    使用方法:

          a. 定义类时确定泛型的类型;

// 定义类时确定泛型类型
public class MyImp1 implements MyGenericInterface<String> {
	@Override
    public void add(String e) {
        // 省略...
    }

	@Override
	public String getE() {
		return null;
	}
}

           b. 始终不确定泛型的类型,直到创建对象时,确定泛型的类型;

// 始终不确定泛型的类型
class MyImp2<E> implements MyGenericInterface<E> {
	@Override
	public void add(E e) {
       	 // 省略...
	}

	@Override
	public E getE() {
		return null;
	}
}

// 直到创建对象时,确定泛型的类型
public class GenericInterface {
    public static void main(String[] args) {
        MyImp2<String>  my = new MyImp2<String>();  
        my.add("aa");
    }
}

 

6.7 泛型通配符:

 不知道使用什么类型来接收的时候,此时可以使用 ? , ? 表示未知通配符。

 泛型的上限与下限:    

     泛型的上限

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

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

     泛型的下限

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

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

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值