一、引入
![]()
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类型,而不是Object
- ArrayList
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(){//返回类型使用E
- return s;
- }
- public void t(){
- System.out.println(s.getClass());//显示s的运行类型
- }
- }
2、泛型的语法:
(1)泛型的声明:
interface接口
//比如:List,ArrayList
说明:
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;
- }
-
- @Override
- public 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
() { - @Override
- public 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;
- }
-
- @Override
- public 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;
- }
-
- @Override
- public 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
() { - @Override
- public int compare(Employee o1, Employee o2) {
- //验证传入的参数
- if(!(o1 instanceof Employee&&o2 instanceof Employee)){
- System.out.println("类型不正确");
- return 0;
- }
- //比较name
- int 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;
- }
-
- @Override
- public 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;
- }
-
- @Override
- public String toString() {
- return "MyDate{" +
- "year=" + year +
- ", month=" + month +
- ", day=" + day +
- '}';
- }
- //把对year-month-day的比较封装到MyDate类里面
- public int compareTo(MyDate o){
- //比较birthday的year
- int yearMinus=year-o.getYear();
- if (yearMinus != 0) {
- return yearMinus;
- }
- //比较birthday的month
- int monthMinus=month-o.getMonth();
- if (monthMinus != 0) {
- return monthMinus;
- }
- //比较birthday的day
- return 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.Integer
- System.out.println("========================");
- car.fly(300,100.1);//当调用方法时,传入参数,编译器就会确定类型
- //class java.lang.Integer
- //class java.lang.Double
-
- System.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
- List
list2=new ArrayList<>(); - List list4=new ArrayList<>();
- List
list5=new ArrayList<>(); -
- //List>
- printCollection1(list1);
- printCollection1(list2);
- printCollection1(list3);
- printCollection1(list4);
- printCollection1(list5);
-
- //List extends A>
- printCollection2(list1);//报错
- printCollection2(list2);//报错
- printCollection2(list3);
- printCollection2(list4);
- printCollection2(list5);
-
- //List super A>
- printCollection3(list1);
- printCollection3(list2);//报错
- printCollection3(list3);
- printCollection3(list4);//报错
- printCollection3(list5);//报错
- }
-
- //方法一:
- //List>表示任意的泛型类型都可以接受
- public static void printCollection1(List> c){
- for(Object object:c){//通配符,取出时,就是Object
- System.out.println(object);
- }
- }
-
- //方法二:
- // extends A>:规定了泛型的上限,可以接受A或A子类
- public static void printCollection2(List extends A> c){
- for(Object object:c){
- System.out.println(object);
- }
- }
-
- //方法三:
- // super A>子类类名A:支持A类以及A类的父类,不限于直接父类,规定了泛型的下限
- public static void printCollection3(List super A> c){
- for(Object object:c){
- System.out.println(object);
- }
- }
- }
- class A{
-
- }
- class B extends A{
-
- }
- class C extends B{
-
- }
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
- list.add(stu.get(keySet));
- }
- return list;
- }
- public void delete(String id){
- System.out.println(stu.remove(id));
- }
- }
- 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;
- }
-
- @Override
- public String toString() {
- return "User{" +
- "id=" + id +
- ", age=" + age +
- ", name='" + name + '\'' +
- '}';
- }
- }
//老师的代码:
- 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");
-
-
- }
- @Test
- public 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;
- }
-
- @Override
- public 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、下次用时就可以自动导入了,点击“小绿箭”就可以运行了
