一、引入
![]()
1、传统方法:
package generic_;import java.util.ArrayList;
@SuppressWarnings({"all"})
public class Generic01 {public static void main(String[] args) {ArrayList arrayList=new ArrayList();arrayList.add(new Dog("旺财",10));arrayList.add(new Dog("发财",1));arrayList.add(new Dog("招财",5));for(Object o:arrayList){Dog dog=(Dog)o;//向下转型System.out.println(dog.getName()+"-"+dog.getAge());}//旺财-10//发财-1//招财-5//如果不小心加入了一只猫,没有报错arrayList.add(new Cat("加菲猫",8));}
}
class Dog{private String name;private int age;public Dog(String name,int age){this.name=name;this.age=age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}
class Cat{private String name;private int age;public Cat(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}
2、使用泛型:
package generic_;import java.util.ArrayList;
@SuppressWarnings({"all"})
public class Generic01 {public static void main(String[] args) {//解读://1、ArrayList表示存放到ArrayList集合中的元素是Dog类型//2、如果编译器发现添加的类型,不满足要求,就会报错//3、在遍历时,可以直接取出Dog类型,而不是ObjectArrayList arrayList=new ArrayList();arrayList.add(new Dog("旺财",10));arrayList.add(new Dog("发财",1));arrayList.add(new Dog("招财",5));arrayList.add(new Cat("加菲猫",8));//报错for(Dog dog:arrayList){System.out.println(dog.getName()+"-"+dog.getAge());}//旺财-10//发财-1//招财-5}
}
class Dog{private String name;private int age;public Dog(String name,int age){this.name=name;this.age=age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}
class Cat{private String name;private int age;public Cat(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}
3、 使用传统方法的问题分析:
(1)不能对加入到集合ArrayList中的数据类型进行约束(不安全)
(2)遍历的时候,需要进行类型转换,如果集合中的数据量较大,对效率有影响
4、泛型的好处
(1)编译时,检查添加元素的类型,提高了安全性
(2)减少了类型转换的次数,提高效率
·不使用泛型
Dog ->加入->object->取出->Dog//放入到Arraylist会先转成Object,在取出时,还需要转换成Dog
·使用泛型
Dog->Dog->Dog//放入时和取出时,不需要类型转换,提高效率
(3)不再提示编译警告
二、基本介绍:(“泛”:a whole group of things, not specific)
1、老韩理解:泛型=>Integer,String,Dog,可以表示数据类型的一种类型
(1)泛型又称参数化类型,是Jdk5.0出现的新特性,解决数据类型的安全性问题
(2)在类声明或实例化时只要指定好需要的具体的类型即可
(3)Java泛型可以保证如果程序在编译时没有发出警告,运行时就不会产生ClassCastException异常。同时,代码更加简洁、健壮
(4)泛型的作用是:可以在类声明时通过一个标识表示类中某个属性的类型,或者是某个方法的返回值的类型,或者是参数类型。
package generic_;public class Generic02 {public static void main(String[] args) {Person person=new Person("韩顺平教育");person.t();//class java.lang.String//此时class Person{}里面的所有的E都用String替换Person person1=new Person(1);person1.t();//class java.lang.Integer//此时class Person{}里面的所有的E都用Integer替换}
}
class Person{E s;//E表示s的数据类型,该数据类型在定义Person对象时指定,即在编译期间,就确定E是什么类型public Person(E s) {//E也可以参数类型this.s = s;}public E f(){//返回类型使用Ereturn s;}public void t(){System.out.println(s.getClass());//显示s的运行类型}
}
2、泛型的语法:
(1)泛型的声明:
interface接口
说明:
1)其中,T,K,V不代表值,而是表示类型
2)任意字母都可以。常用T表示,是Type的缩写
(2)泛型的实例化:
要在类名后面指定类型参数的值(类型)。如:
1)List
2) Iterator
(3)
//我的代码:
package generic_;import java.util.*;@SuppressWarnings({"all"})
public class TestGeneric2 {public static void main(String[] args) {Student student=new Student();Student student1=new Student();Student student2=new Student();HashSet hashSet=new HashSet();hashSet.add(student);hashSet.add(student1);hashSet.add(student2);HashMap hashMap = new HashMap();hashMap.put("jack",student);hashMap.put("tom",student1);hashMap.put("smith",student2);System.out.println("====================");Set keyset=hashMap.keySet();for (Object key :keyset) {System.out.println(key+"-"+hashMap.get(key));}System.out.println("====================");Set entrySet=hashMap.entrySet();for (Object entry:entrySet) {Map.Entry m=(Map.Entry)entry;System.out.println(m.getKey()+"-"+m.getValue());}}
}
class Student{E student;
}
//====================
//tom-generic_.Student@4f3f5b24
//smith-generic_.Student@15aeb7ab
//jack-generic_.Student@27d6c5e0
//====================
//tom-generic_.Student@4f3f5b24
//smith-generic_.Student@15aeb7ab
//jack-generic_.Student@27d6c5e0
//老师的代码:
package generic_;
import java.util.*;@SuppressWarnings({"all"})
public class TestGeneric2 {public static void main(String[] args) {HashSet students=new HashSet();students.add(new Student("jack",18));students.add(new Student("tom",28));students.add(new Student("mary",19));for (Student student :students) {System.out.println(student);}HashMap hm = new HashMap();hm.put("tom",new Student("tom",28));hm.put("smith",new Student("smith",48));hm.put("hsp",new Student("hsp",28));//迭代器/*自动填充的原因(hm.entrySet().var):public Set> entrySet(){Set> es;return (es=entrySet)==null?(entrySet=new EntrySet()):es;}*/Set> entries = hm.entrySet();/*自动填充的原因(entries.iterator().var):public final Iterator> iterator(){return new EntryIterator();}*/Iterator> iterator = entries.iterator();System.out.println("===========================");while (iterator.hasNext()) {Map.Entry next=iterator.next();System.out.println(next.getKey()+"-"+next.getValue());}}
}
//Student{name='mary', age=19}
//Student{name='jack', age=18}
//Student{name='tom', age=28}
//===========================
//tom-Student{name='tom', age=28}
//smith-Student{name='smith', age=48}
//hsp-Student{name='hsp', age=28}
class Student{private String name;private int age;public Student(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}';}
}
3、泛型使用的注意事项和细节:
(1)interface List
说明:T,E只能是引用类型,不能是基本数据类型
看看下面语句是否正确?:
List
List
(2)在指定泛型具体类型后,可以传入该类型或者其子类类型
(3)泛型使用形式
List
List
(4)如果我们这样写List list3=new ArrayList();默认给它的泛型是[
4、课堂练习题

//我的代码:
package generic_;import java.util.ArrayList;
import java.util.Comparator;@SuppressWarnings({"all"})
public class GenericExercise01 {public static void main(String[] args) {ArrayList arrayList=new ArrayList();Employee jack = new Employee("jack", 10000, new MyDate(2000, 1, 1));Employee tom = new Employee("tom", 20000, new MyDate(2001, 1, 1));Employee smith = new Employee("smith", 30000, new MyDate(2002, 1, 1));arrayList.add(jack);arrayList.add(tom);arrayList.add(smith);arrayList.sort(new Comparator() {@Overridepublic int compare(Employee o1, Employee o2) {if(o1.getName().equals(o2.getName())){if(o1.getBirthday()==o2.getBirthday()){}else if(o1.getBirthday().getYear()==o2.getBirthday().getYear()){if(o1.getBirthday().getMonth()==o2.getBirthday().getMonth()){if(o1.getBirthday().getDay()==o2.getBirthday().getDay()){return 0;}else{return o1.getBirthday().getDay()-o2.getBirthday().getDay();}}else{return o1.getBirthday().getMonth()-o2.getBirthday().getMonth();}}else{return o1.getBirthday().getYear()-o1.getBirthday().getYear();}}else{return o1.getName().length()-o2.getName().length();}return 0;}});System.out.println(arrayList);//[Employee{name='tom', sal=20000.0, birthday=MyDate{year=2001, month=1, day=1}}, Employee{name='jack', sal=10000.0, birthday=MyDate{year=2000, month=1, day=1}}, Employee{name='smith', sal=30000.0, birthday=MyDate{year=2002, month=1, day=1}}]}
}
class Employee{private String name;private double sal;private MyDate birthday;public Employee(String name, double sal, MyDate birthday) {this.name = name;this.sal = sal;this.birthday = birthday;}public String getName() {return name;}public void setName(String name) {this.name = name;}public double getSal() {return sal;}public void setSal(double sal) {this.sal = sal;}public MyDate getBirthday() {return birthday;}public void setBirthday(MyDate birthday) {this.birthday = birthday;}@Overridepublic String toString() {return "Employee{" +"name='" + name + '\'' +", sal=" + sal +", birthday=" + birthday +'}';}
}
class MyDate{private int year;private int month;private int day;public MyDate(int year, int month, int day) {this.year = year;this.month = month;this.day = day;}public int getYear() {return year;}public void setYear(int year) {this.year = year;}public int getMonth() {return month;}public void setMonth(int month) {this.month = month;}public int getDay() {return day;}public void setDay(int day) {this.day = day;}@Overridepublic String toString() {return "MyDate{" +"year=" + year +", month=" + month +", day=" + day +'}';}
}
//老师的代码:
package generic_;import java.util.ArrayList;
import java.util.Comparator;@SuppressWarnings({"all"})
public class GenericExercise01 {public static void main(String[] args) {ArrayList employees=new ArrayList();employees.add(new Employee("jack", 10000, new MyDate(2000, 1, 1)));employees.add(new Employee("tom", 20000, new MyDate(2001, 1, 1)));employees.add(new Employee("smith", 30000, new MyDate(2002, 1, 1)));System.out.println("employees="+employees);employees.sort(new Comparator() {@Overridepublic int compare(Employee o1, Employee o2) {//验证传入的参数if(!(o1 instanceof Employee&&o2 instanceof Employee)){System.out.println("类型不正确");return 0;}//比较nameint i=o1.getName().compareTo(o2.getName());if (i != 0) {return i;}return o1.getBirthday().compareTo(o2.getBirthday());}});System.out.println("=========排序后=========");System.out.println("employees="+employees);}
}
//employees=[
//Employee{name='jack', sal=10000.0, birthday=MyDate{year=2000, month=1, day=1}},
//Employee{name='tom', sal=20000.0, birthday=MyDate{year=2001, month=1, day=1}},
//Employee{name='smith', sal=30000.0, birthday=MyDate{year=2002, month=1, day=1}}]
//=========排序后=========
//employees=[
//Employee{name='jack', sal=10000.0, birthday=MyDate{year=2000, month=1, day=1}},
//Employee{name='smith', sal=30000.0, birthday=MyDate{year=2002, month=1, day=1}},
//Employee{name='tom', sal=20000.0, birthday=MyDate{year=2001, month=1, day=1}}]
class Employee{private String name;private double sal;private MyDate birthday;public Employee(String name, double sal, MyDate birthday) {this.name = name;this.sal = sal;this.birthday = birthday;}public String getName() {return name;}public void setName(String name) {this.name = name;}public double getSal() {return sal;}public void setSal(double sal) {this.sal = sal;}public MyDate getBirthday() {return birthday;}public void setBirthday(MyDate birthday) {this.birthday = birthday;}@Overridepublic String toString() {return '\n'+"Employee{" +"name='" + name + '\'' +", sal=" + sal +", birthday=" + birthday +'}';}
}
class MyDate{private int year;private int month;private int day;public MyDate(int year, int month, int day) {this.year = year;this.month = month;this.day = day;}public int getYear() {return year;}public void setYear(int year) {this.year = year;}public int getMonth() {return month;}public void setMonth(int month) {this.month = month;}public int getDay() {return day;}public void setDay(int day) {this.day = day;}@Overridepublic String toString() {return "MyDate{" +"year=" + year +", month=" + month +", day=" + day +'}';}//把对year-month-day的比较封装到MyDate类里面public int compareTo(MyDate o){//比较birthday的yearint yearMinus=year-o.getYear();if (yearMinus != 0) {return yearMinus;}//比较birthday的monthint monthMinus=month-o.getMonth();if (monthMinus != 0) {return monthMinus;}//比较birthday的dayreturn day-o.getDay();}
}
5、自定义泛型(1)基本语法:
class类名{//可以有多个泛型成员}
(2)注意细节:
1)普通成员可以使用泛型(属性、方法)
2)使用泛型的数组,不能初始化
3)静态方法中不能使用类的泛型
4)泛型类的类型,是在创建对象时确定的(因为创建对象时,需要指定确定类型)
5)如果在创建对象时,没有指定类型,默认为Object
package generic_;import java.util.ArrayList;
@SuppressWarnings({"all"})
public class CustomMethodGeneric {public static void main(String[] args) {Car car = new Car();car.fly("宝马",100);//当调用方法时,传入参数,编译器就会确定类型//class java.lang.String//class java.lang.IntegerSystem.out.println("========================");car.fly(300,100.1);//当调用方法时,传入参数,编译器就会确定类型//class java.lang.Integer//class java.lang.DoubleSystem.out.println("========================");Fish fish = new Fish<>();fish.hello(new ArrayList(),11.3f);//class java.util.ArrayList//class java.lang.Float}
}
class Car{//普通类public void run(){}//1、就是泛型//2、是提供给fly使用的,不是返回类型public void fly(T t,R r){//泛型方法System.out.println(t.getClass());//自动装箱,String / Integer / Double...System.out.println(r.getClass());//自动装箱,String / Integer / Double...}
}
class Fish{//泛型类public void run(){}public void eat(U u,M m){//泛型方法}//1、hi()方法不是泛型方法//2、是hi()方法使用了类声明的泛型//3、泛型方法 和 方法使用泛型 是不一样的public void hi(T t){}//泛型方法,可以使用类声明的泛型,也可以使用自己声明泛型public void hello(R r,K k){//(R r,K k)中的R来自类的声明处,K来自方法的定义处System.out.println(r.getClass());System.out.println(k.getClass());}
}
6、泛型的继承和通配符:
(1)泛型不具备继承性
List
package generic_;import java.util.ArrayList;
import java.util.List;public class GenericExtends {public static void main(String[] args) {List
7、
//我的代码:
package generic_;import java.util.List;
import java.util.Map;
import java.util.Set;@SuppressWarnings({"all"})
public class Homework01 {public static void main(String[] args) {User jack = new User(1, 18, "jack");User tom = new User(2, 19, "tom");User smith = new User(3, 20, "smith");}
}
class DAO{Map stu;public DAO(Map stu) {this.stu = stu;}public void save(String id, T entity){System.out.println(stu.put(id,entity));}public T get(String id){return stu.get(id);}public void update(String id,T entity){System.out.println(stu.replace(id,entity));}public List list(){Set keySet=stu.keySet();List list=null;int size=stu.size();for(int i=0;i
//老师的代码:
package generic_;import innerclass.D;
import org.junit.Test;import java.util.List;
import java.util.Map;
import java.util.Set;@SuppressWarnings({"all"})
public class Homework01 {public static void main(String[] args) {User jack = new User(1, 18, "jack");User tom = new User(2, 19, "tom");User smith = new User(3, 20, "smith");}@Testpublic void testList(){DAO dao=new DAO<>();dao.save("001",new User(1,10,"jack"));dao.save("002",new User(2,18,"king"));dao.save("003",new User(3,38,"smith"));List list=dao.list();System.out.println("list="+list);System.out.println("==============================");dao.update("003",new User(3,58,"milan"));dao.delete("001");list=dao.list();System.out.println("list="+list);System.out.println("==============================");System.out.println("id==003:"+dao.get("003"));}
}
//list=[User{id=1, age=10, name='jack'}, User{id=2, age=18, name='king'}, User{id=3, age=38, name='smith'}]
//==============================
//list=[User{id=2, age=18, name='king'}, User{id=3, age=58, name='milan'}]
//==============================
//id==003 User{id=3, age=58, name='milan'}
package generic_;import java.util.*;public class DAO{private Map map=new HashMap<>();//搞清楚怎么定义这个成员变量的public void save(String id, T entity){map.put(id,entity);}public T get(String id){return map.get(id);}public void update(String id,T entity){map.put(id,entity);}//遍历map[k-v],将map的所有value(T entity),封装到ArrayList返回即可public List list(){List list = new ArrayList<>();Set keySet=map.keySet();for (String key:keySet) {list.add(map.get(key));}return list;}public void delete(String id){map.remove(id);}
}
package generic_;public class User{private int id;private int age;private String name;public User(int id, int age, String name) {this.id = id;this.age = age;this.name = name;}public int getId() {return id;}public void setId(int id) {this.id = id;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "User{" +"id=" + id +", age=" + age +", name='" + name + '\'' +'}';}
}
三、JUnit
1、为什么需要JUnit?
(1) 一个类有很多功能代码需要测试,为了测试,就需要写入到main方法中
(2) 如果有多个功能代码测试,就需要来回注销,切换很麻烦
(3)如果可以直接运行一个方法,就方便很多,并且可以给出相关信息,就好了
2、基本介绍:
(1)JUnit是一个Java语言的单元测试框架
(2)多数Java的开发环境都已经集成了JUnit作为单元测试的工具
3、操作:
(1)在要测试的方法上面写“@Test”

2、快捷键alt+enter,“Add 'JUnit5.4' to classpath”,选最新的就行了

3、下次用时就可以自动导入了,点击“小绿箭”就可以运行了
