以下是一些基础的泛型案例,通过在案例中对泛型更加深入的去学习:
1 泛型类
/**
* 泛型类是带有一个或多个类型参数的类
* */
class Entry<K,V>{
private K key;
private V value;
public Entry(K key, V value) {
this.key = key;
this.value = value;
}
public K getKey(){
return this.key;
}
public V getValue(){
return this.value;
}
public void setKey(K key){
this.key = key;
}
public void setValue(V value){
this.value = value;
}
}
public class FirstGN {
public static void main(String[] args){
Entry<Integer,String> entry = new Entry<>(1,"社会"); // 砖石语法,构造函数的类型是推出来的
System.out.println(entry.getKey()); // 1
System.out.println(entry.getValue()); // 社会
}
}
2.泛型方法
/**
* 泛型方法:
* 指带有类型参数的方法
* 声明一个泛型方法时,类型参数要放在访问修饰符之后和返回类型之前
*
* **/
class Array{
// 这个就和之前遇到的Android中的很像了
// 泛型方法中,参数类型一定要置于修饰符与返回值之间 <>
public static <T> T[] swap(T[] array,int i,int j){
T temp = array[i];
array[i] = array[j];
array[j] = temp;
return array;
}
}
public class FirstGN {
public static void main(String[] args){
Integer[] arr = {1,2};
System.out.println(arr[0]+" "+arr[1]); //1 2
Integer[] swap = Array.swap(arr, 0, 1);
System.out.println(swap[0]+" "+swap[1]); // 2 1
}
}
3.类型限定
/***
*类型限定
* 对类型参数进行限定要求该类型实现某些类或者继承某个接口
* 多个限制这样写 <T extends AA & BB >
* */
class A{
String value;
public A(String value) {
this.value = value;
}
@Override
public String toString() {
return value;
}
}
class B extends A{
public B(String value) {
super(value);
}
}
class TypeLimit{
public static <T extends A> void show(ArrayList<T> mList){
System.out.println(mList);
}
}
public class FirstGN {
public static void main(String[] args){
ArrayList<B> mArrayB = new ArrayList<>();
mArrayB.add(new B("你好"));
mArrayB.add(new B("中国"));
TypeLimit.show(mArrayB);
/* ArrayList<String> mListStr = new ArrayList<>();
mListStr.add("123");
TypeLimit.show(mListStr); // 报错如下:类型被限定了的
show(java.util.ArrayList<T>) in TypeLimit cannot be applied
to (java.util.ArrayList<java.lang.String>)
*/
}
}
4. 通配符
4.1 子类型通配符
/**子类型通配符
* 控制只读不写的
* 可以将 ? extends A 转换为 A
* 但不能将 A 转换为 ? extends A
* */
class Employee{
public String name;
public Employee(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
class Manager extends Employee{
public Manager(String name) {
super(name);
}
}
class SubMatchChar{
public static void printName(ArrayList<? extends Employee> staff){
for (int i=0;i<staff.size();i++){
Employee employee = staff.get(i);
System.out.print(employee.getName()+" ");
}
/*
添加如下会报错
* add(capture<? extends dailystudy.eve_18_4_26.genericity.Employee>)
in ArrayList cannot be applied to(dailystudy.eve_18_4_26.genericity.Employee)
staff.add(new Manager("111"));
staff.add(new Employee("111"));
* */
}
}
public class FirstGN {
public static void main(String[] args){
ArrayList<Employee> employeeArrayList = new ArrayList<>();
employeeArrayList.add(new Employee("小张"));
employeeArrayList.add(new Employee("小李"));
SubMatchChar.printName(employeeArrayList); // 小张 小李
ArrayList<Manager> managerArrayList = new ArrayList<>();
managerArrayList.add(new Manager("王总"));
managerArrayList.add(new Manager("白总"));
SubMatchChar.printName(managerArrayList); // 王总 白总
}
}
4.2 父类型通配符
/***
* 父类型通配符
* 当给方法指定一个泛型函数式接口的参数时,应该使用super通配符
* 当期望一个函数能够处理EmPlyee对象时,编写一个能够处理任意对象的函数就需要这样做
* */
class Employee extends MPerson{
public String name;
public int Salary;
public Employee(String name, int salary) {
super(name);
this.name = name;
Salary = salary;
}
public int getSalary() {
return Salary;
}
public Employee(String name) {
super(name);
this.name = name;
}
public String getName() {
return name;
}
}
interface Predicate<T> {
// 这里能写成lambda的前提是只有1个抽象方法的接口对象
// 这样的方法称为函数式接口
boolean test(T tag);
}
class Show{
public static void printAll(Employee[] staff,Predicate<? super Employee> filter){
for (Employee employee:staff){
if (filter.test(employee))
System.out.println(employee.getName());
}
}
}
class AAA implements Predicate<Employee>{
@Override
public boolean test(Employee tag) {
return tag.getSalary() < 150;
}
}
public class FirstGN {
public static void main(String[] args){
Employee[] employees = new Employee[2];
employees[0] = new Employee("小李",200);
employees[1] = new Employee("小王",100);
Show.printAll(employees,e -> e.getSalary() < 150); // 小王
Show.printAll(employees,e -> e.name.equals("小李")); // 小李
}
4.3 其他通配符
/**
* 带类型变量的通配符 T extends Comparable<? super T> 例子就不举了
* 无限定的通配符 ?
* */
class Check{
public static boolean hasNull(ArrayList<?> mList){
for (Object o : mList){
if (null == o){
return true;
}
}
return false;
}
}
public class FirstGN {
public static void main(String[] args){
ArrayList<String> mlist = new ArrayList<>();
mlist.add("1111");
mlist.add(null);
System.out.println(Check.hasNull(mlist)); //true
}
目前先这些 还是要巩固的