泛型
在此之前的集合,我们使用的时候,可以传入不同的数据类型的元素。
但是,实际开发中,一个集合只能够存储一种数据类型,为了就是将来获取元素处理的时候,处理方式能够统一
之前也学习过一种容器,这种容器在定义的时候,就明确了元素的数据类型(数组)
现在集合想要模仿使用定义数组时的特点,可以明确一个集合元素的数据类型。java为了实现这样的功能,提供了一个技术给我们使用:泛型
语句定义格式:<引用数据类型>
泛型的好处:
1、消除了程序中大部分的黄色警告
2、在获取元素的时候,不需要做向下转型
3、限制了集合存储的数据类型,将来处理的方式统一
package com.shujia.day13;
import java.util.ArrayList;
import java.util.Iterator;
public class ArrayListDemo1 {
public static void main(String[] args) {
//加入泛型创建集合对象
//ArrayList<E>()
ArrayList<String> list = new ArrayList<String>();//这里前面写了类型,后面的<>就可以不写了,能自动判断类型
//String[] arr; 类似数组的定义
//创建元素对象并添加到集合中
list.add("java");
list.add("hadoop");
list.add("hive");
list.add("java");
list.add("hbase");
// list.add(12); //因为前面限制了只能放String类型的,这里无法存放int类型的
//迭代器遍历
Iterator<String> iterator= list.iterator();
while(iterator.hasNext()){
String s= iterator.next(); //现在不需要进行向下转型,直接获取元素
}
}
}
package com.shujia.day13;
/*
1.开发代码的时候,写的泛型,将来使用的时候,应该传入一个引用数据类型给到开发时的泛型中接收
2.可以将类当作参数一样进行传递
<>中应该定义一个变量,用于接收将来使用时传入的引用数据类型,优点类似形式参数的味道
3.要符合标识符的命名规则
将来开发时,如果泛型中只需要接收一个引用数据类型,定义时,只需要写一个大写的字母
*/
class Demo1<E>{
//E在一个类中是唯一的
public void fun1(E a){
System.out.println(a);
}
}
/*
泛型类:在开发代码的时候,将泛型写在类上
*/
public class FanXingDemo1 {
public static void main(String[] args) {
Demo1<String> stringDemo1=new Demo1<>();
stringDemo1.fun1("12");
}
}
package com.shujia.day13;
class Demo2{
//泛型方法,将来调用时可以传入任意的数据类型,与类上面的泛型无关
public <E> void fun1(E e){
System.out.println(e);
}
}
/*
泛型方法:将泛型定义在方法上
*/
public class FanXingDemo2 {
public static void main(String[] args) {
Demo2 demo2 = new Demo2();
demo2.fun1("da");
demo2.fun1(12);
demo2.fun1(12.34);
}
}
package com.shujia.day13;
import java.util.ArrayList;
import java.util.List;
interface Inter<E>{
void fun1(E e);
}
//如果一个类实现一个接口,这个接口有泛型的话,在类定义的时候也要有泛型,一般情况下与接口的泛型写法一致
class Demo3<E> implements Inter<E>{
@Override
public void fun1(E e) {
}
}
/*
泛型接口:将泛型定义在接口上
*/
public class FanXingDemo3 {
public static void main(String[] args) {
Inter<String> s=new Demo3<>();
s.fun1("ababa");
/*
interface List<E>
class ArrayList<E> implements List<E>{
add(E e){}
}
*/
ArrayList<String> list = new ArrayList<>();
list.add("asdf");
System.out.println(list);
}
}
开发程序时,泛型的高级用法:
泛型通配符 :
<?>
任意类型,如果没有明确,那么就是Object以及任意的Java类了
package com.shujia.day13;
import java.util.ArrayList;
class Animal{
}
class Dog extends Animal{
}
class Cat extends Animal{
}
public class FanXingDemo4 {
public static void main(String[] args) {
ArrayList<?> list1 = new ArrayList<Dog>();//这里前面的填了?,后面的类可以填任意的
}
}
? extends E
向下限定,E及其子类
package com.shujia.day13;
import java.util.ArrayList;
/*
开发程序时,泛型的高级用法:
泛型通配符<?>
任意类型,如果没有明确,那么就是Object以及任意的Java类了
? extends E
向下限定,E及其子类
? super E
向上限定,E及其父类
*/
class Animal{
}
class Dog extends Animal{
}
class Cat extends Animal{
}
public class FanXingDemo4 {
public static void main(String[] args) {
// ArrayList<Animal> list1 = new ArrayList<>();
//向下限定
// ArrayList<? extends Animal> list1 = new ArrayList<Object>();
ArrayList<? extends Animal> list1 = new ArrayList<Dog>();
}
}
Collection<? extends E> 表示将来应该传入一个Collection集合对象,并且集合中的元素类型是E本身或者是E的子类类型(注意红色方框处填写的是无法传入的)
现在来创建一个新的类Demo4
package com.shujia.day13;
import java.util.ArrayList;
import java.util.Collection;
class Animal{
}
class Dog extends Animal{
}
class Cat extends Animal{
}
class Demo4<E>{
public void fun1(Collection<? super E> e){
}
}
public class FanXingDemo4 {
public static void main(String[] args) {
ArrayList<Animal> list1 = new ArrayList<>();
//向上限定
Demo4<Animal> d = new Demo4<>();
//fun1(Collection<? super E> e)
//Collection<? super E> 表示将来应该传入一个Collection集合对象,但是集合中的元素类型只能是E的本身类型或者E的父类类型
ArrayList<Dog> list2 = new ArrayList<>();
ArrayList<Cat> list3 = new ArrayList<>();
ArrayList<Object> list4 = new ArrayList<>();
// d.fun1(list2);
// d.fun1(list3);
d.fun1(list4);
d.fun1(list1);
}
}