Java——集合2-4(泛型)

泛型

泛型概述

泛型:是JDK5中引入的特性,它提供了编译时类型安全检测机制,该机制允许在编译时检测到非法的类型
它的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数
一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参。那么参数化类型如何理解?
顾名思义,就是将类型有原来的具体的类型参数化,然后再使用/调用时传入具体的类型
这种参数类型可以用在类、方法和接口中,分别被称为泛型类、泛型方法、泛型接口

泛型定义格式
<类型> 指定一种类型的格式。这里的类型可以看成是形参
<类型1,类型2…> 指定多种类型的格式,多种类型之间用逗号隔开。这里的类型可以看成是形参

泛型的好处:

  • 把运行时问题提前,转到了编译期间,便于修改问题
  • 可以直接赋值给其他类型,避免出现强制类型转换

例如:

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

/*
泛型

需求:Collection集合存储字符串并遍历
*/
public class GenericDemo {
    
    
	public static void main(String[] args) {
    
    
		//创建集合对象
//		Collection c=new ArrayList();
		Collection<String> c = new ArrayList<String>();

		//添加元素
		c.add("hello");
		c.add("world");
		c.add("java");
		//		c.add(100);//运行时期问题改为编译期问题

		//遍历集合
//		Iterator it = c.iterator();
		Iterator<String> it = c.iterator();
		while (it.hasNext()) {
    
    
//			Object obj = it.next();
//			System.out.println(obj);

			//向下转型
//			String s=(String)it.next();//运行时问题:ClassCastException
			String s = it.next();//不需要强制类型转换
			System.out.println(s);
		}

	}

运行结果:
在这里插入图片描述

泛型类

  • 格式:修饰符 class 类名<类型>{}

<>中表示泛型的参数可以是任意标识,常见的如T、E、K、V


//学生类
public class Student {
    
    
	private String name;

	public String getName() {
    
    
		return name;
	}

	public void setName(String name) {
    
    
		this.name = name;
	}

}

//老师类
public class Teacher {
    
    
	private Integer age;

	public Integer getAge() {
    
    
		return age;
	}

	public void setAge(Integer age) {
    
    
		this.age = age;
	}

}

/*
泛型类的定义格式:

- 格式:修饰符 class 类名<类型>{}
- 范例:public class Generic<T>{}
此处**T**可以随便写为任意标识,常见的如**T、E、K、V**等形式的参数常用于表示泛型
*/

public class Generic<T> {
    
    
	private T t;

	public T getT() {
    
    
		return t;
	}

	public void setT(T t) {
    
    
		this.t = t;
	}

}

//测试类
public class GenericDemo {
    
    
	public static void main(String[] args) {
    
    
		Student s = new Student();
		s.setName("小白");
		System.out.println(s.getName());

		Teacher t = new Teacher();
		t.setAge(23);
		//		t.setAge("34");//报错
		System.out.println(t.getAge());
		System.out.println("--------");

		Generic<String> g1 = new Generic<String>();
		g1.setT("小黑");
		System.out.println(g1.getT());

		Generic<Integer> g2 = new Generic<Integer>();
		g2.setT(12);
		System.out.println(g2.getT());

		Generic<Boolean> g3 = new Generic<Boolean>();
		g3.setT(true);
		System.out.println(g3.getT());

	}
}

运行结果:
在这里插入图片描述
泛型方法
泛型方法的定义格式:

  • 格式:修饰符<类型> 返回值类型 方法名(类型 变量名){ }

/*
泛型类
public class Generic<T>{
	
//	public void show(String s) {
//		System.out.println(s);
//	}
//	
//	public void show(Integer i) {
//		System.out.println(i);
//	}
//	
//	public void show(boolean b) {
//		System.out.println(b);
//	}

	public void show(T t) {
		System.out.println(t);
		}
	
}

*/
/*泛型方法改进*/
public class Generic {
    
    
	public <T> void show(T t) {
    
    
		System.out.println(t);
	}
}

//测试类
public class GenericDemo2 {
    
    
	public static void main(String[] args) {
    
    
		/*Generic g=new Generic();
		
		g.show("小白");
		g.show(24);
		g.show(true);*/

		/*Generic<String> g1=new Generic<String>();
		g1.show("小白");
		
		Generic<Integer> g2=new Generic<Integer>();
		g2.show(24);
		
		Generic<Boolean> g3=new Generic<Boolean>();
		g3.show(true);*/

		Generic g = new Generic();
		g.show("小白");
		g.show(24);
		g.show(true);
		g.show(12.34);

	}
}

运行结果:
在这里插入图片描述
泛型接口

泛型接口的定义格式:

  • 格式:修饰符 interface 接口名<类型>{ }

//泛型接口
public interface Generic1<T> {
    
    
	void show(T t);
}


//泛型类继承接口
public class Genriclmpl<T> implements Generic1<T> {
    
    
	@Override
	public void show(T t) {
    
    
		// TODO Auto-generated method stub
		System.out.println(t);
	}
}
//测试类
public class GenericDemo3 {
    
    
	public static void main(String[] args) {
    
    
		Generic1<String> g1 = new Genriclmpl<String>();
		g1.show("小白");

		Generic1<Integer> g2 = new Genriclmpl<Integer>();
		g2.show(23);

		Generic1<Boolean> g3 = new Genriclmpl<Boolean>();
		g3.show(true);

	}
}

运行结果:
在这里插入图片描述
类型通配符:<?>

使用类型通配符,可以用于表示各种泛型List的父类
若希望它代表某一类泛型List的父类,可以使用类型通配符的上限
若希望它代表某一类泛型List的子类,可以使用类型通配符的下限

名称 举例 说明
类型通配符<?> List<?> 表示元素类型未知的List,它的元素可以匹配任何的类型
类型通配符上限<? extends 类型> List<? extends Number> 它表示的类型是Number或者其子类型
类型通配符下限:<? super 类型> List<? extends Number> 它表示的类型是Number或者其父类型
import java.util.ArrayList;
import java.util.List;

/*
**类型通配符**

为了表示各种泛型List的父类,可以使用类型通配符

 - 类型通配符:**<?>**
 - List<?>:表示元素类型未知的List,它的元素可以匹配**任何的类型**
 - 这种带通配符的List仅表示它是各种泛型List的父类,并不能把元素添加到其中

如果说我们不希望List<?>是任何泛型List的父类,只希望它代表某一类泛型List的父类,可以使用类型通配符的上限

 - 类型通配符上限:**<? extends 类型>**
 - List<? extends Number>:它表示的类型是**Number或者其子类型**

除了可以指定类型通配符的上限,我们也可以指定类型通配符的下限

 - 类型通配符下限:**<? super 类型>**
 - List<? super Number>:它表示的类型是**Number或者其父类型**
*/

public class GenericDemo4 {
    
    
	public static void main(String[] args) {
    
    
		//类型通配符:<?>
		List<?> list1 = new ArrayList<Object>();
		List<?> list2 = new ArrayList<Number>();
		List<?> list3 = new ArrayList<Integer>();
		System.out.println("--------");

		// 类型通配符上限:<? extends 类型>
		//		List<? extends Number> list4=new ArrayList<Object>();//报错
		List<? extends Number> list5 = new ArrayList<Number>();
		List<? extends Number> list6 = new ArrayList<Integer>();
		System.out.println("--------");

		//类型通配符下限:<? super 类型>
		List<? super Number> list7 = new ArrayList<Object>();
		List<? super Number> list8 = new ArrayList<Number>();
		//		List<? super Number> list9=new ArrayList<Integer>();//报错

	}
}

可变参数

可变参数又称参数个数可变,用作方法的形参出现,那么方法参数个数就是可变的了

  • 格式:修饰符 返回值类型 方法名(数据类型… 变量名){ }
  • 范例:public static int sum(int… a){ }

可变参数注意事项:

  • 这里的变量其实是一个数组
  • 如果一个方法有多个参数,包含可变参数,可变参数要放在最后
public class ArgsDemo {
    
    
	public static void main(String[] args) {
    
    
		System.out.println(sum(1, 2));
		System.out.println(sum(1, 2, 3));
		System.out.println(sum(1, 2, 3, 4));

		System.out.println(sum(1, 2, 3, 4, 5));
		System.out.println(sum(1, 2, 3, 4, 5, 6));
		System.out.println(sum(1, 2, 3, 4, 5, 6, 7));

	}

	//	public static int sum(int... a,int b) {//报错
	//		return 0;
	//	}

	//	public static int sum(int b,int... a) {//可变参数要放在后面
	//		return 0;
	//	}
	
	public static int sum(int... a) {
    
    
		//		System.out.println(a);
		//		return 0;
		int sum = 0;
		for (int i : a) {
    
    
			sum += i;
		}
		return sum;

	}

	//	public static int sum(int a,int b) {
    
    
	//		return a+b;
	//	}
	//	public static int sum(int a,int b,int c) {
    
    
	//		return a+b+c;
	//	}
	//	public static int sum(int a,int b,int c,int d) {
    
    
	//		return a+b+c+d;
	//	}
}

运行结果:
在这里插入图片描述
可变参数的使用

方法说明 格式 说明 特点
Arrays工具类中有一个静态方法 public static List asList(T… a) 返回由指定数组支持的固定大小的列表 不能做增删操作,可以做修改操作
List接口中有一个静态方法 public static List of(E… elements) 返回包含任意数量元素的不可变列表 不能做增删改操作
Set接口中有一个静态方法 public static Set of(E… elements) 返回包含任意数量元素的不可变集合 不能给重复的元素,不能做增删操作,没有修改的方法
import java.util.Arrays;
import java.util.List;
import java.util.Set;

/*
Arrays工具类中有一个静态方法:

- public static <T> List<T> asList(T... a):返回由指定数组支持的固定大小的列表

List接口中有一个静态方法:

- public static <E> List<E> of(E... elements):返回包含任意数量元素的不可变列表

Set接口中有一个静态方法:

- public static <E> Set<E> of(E... elements):返回包含任意数量元素的不可变集合
*/

public class ArgsDemo2 {
    
    
	public static void main(String[] args) {
    
    
		
		//public static <T> List<T> asList(T... a):返回由指定数组支持的固定大小的列表
		List<String> list = Arrays.asList("hello","world","java");
		
//		list.add("javaee");//UnsupportedOperationException:不支持请求操作
//		list.remove("world");//UnsupportedOperationException
		list.set(1,"javaee");//添加和删除都会修改List的大小,所以不可以用,修改不会改变大小,可以用
		System.out.println(list);
		
		
		
		//public static <E> List<E> of(E... elements):返回包含任意数量元素的不可变列表
		List<String> list = List.of("hello","world","java","world");
		
//		list.add("javaee");//UnsupportedOperationException
//		list.remove("world");//UnsupportedOperationException
//		list.set(1,"javaee");//UnsupportedOperationException
		//增删改都不可以
		System.out.println(list);
		
		
		
		//public static <E> Set<E> of(E... elements):返回包含任意数量元素的不可变集合
		Set<String> set = Set.of("hello","world","java");
//		Set<String> set = Set.of("hello","world","java","world");//IllegalArgumentException:非法或不正确的参数
		//因为set不能有重复元素
		
//		set.add("javaee");//UnsupportedOperationException
//		set.remove("world");//UnsupportedOperationException	
		System.out.println(set);
		
	}
}

猜你喜欢

转载自blog.csdn.net/weixin_47678894/article/details/119373395
2-4