泛型的理解
泛型的引入
泛型,就是允许在定义类,接口时通过一个"标识",表示类中某个’属性的类型’ 或者是某个方法的"返回值或参数的类型". 这个类型参数将在使用时确定
泛型的使用
未使用泛型 所遇到的问题
@Test
public void test1(){
//未集合中使用泛型的场景
ArrayList list = new ArrayList();
list.add(67);
list.add(33);
list.add(98);
list.add(99);
//问题1 , 类型不安全,add()的参数是Object类型,意味着任何类型的对象都可以添加成功
// list.add("AA");
Iterator iterator = list.iterator();
while(iterator.hasNext()){
//问题二, 需要使用强转操作,繁琐,还有可能导致ClassCastException异常
Integer i = (Integer) iterator.next();
int score = i;
System.out.println(score);
}
}
使用泛型后的情况
public void test2(){
//在集合中使用泛型的例子
List<Integer> list = new ArrayList<Integer>();
list.add(12);
list.add(34);
list.add(56);
list.add(78);
//list.add("aa");
//添加非Integer类型的数据时,会导致编译报错 以 保证类型的安全
Iterator<Integer> iterator = list.iterator();
while(iterator.hasNext()){
Integer i = iterator.next();
//使用泛型后的集合,添加的类型都是Integer类型,避免了强转的操作
int score = i;
System.out.println(score);
}
}
Map中使用泛型的情况
public void test3(){
// HashMap<String,Integer> map = new HashMap<String,Integer>();
HashMap<String, Integer> map = new HashMap<>(); //类型推断
map.put("Jerry",67);
map.put("Tom",68);
map.put("Rose",99);
// Set<Map.Entry<String, Integer>> entrySet = map.entrySet();
// Iterator<Map.Entry<String, Integer>> iterator = entrySet.iterator();
//或者使用 var
var entrySet = map.entrySet(); //类型推断
var iterator = entrySet.iterator(); //类型推断
while (iterator.hasNext()){
Map.Entry<String, Integer> entry = iterator.next();
Integer value = entry.getValue();
String key = entry.getKey();
System.out.println(key +"--->"+value);
}
}
使用说明
- 集合框架在声明接口和其实现类时,使用了泛型(jdk5.0) 在实例化集合对象时,如果没有使用泛型,则认为操作的是Object类型的数据
- 如果使用了泛型,则需要知名泛型的具体类型,一旦指明了泛型的具体类型,则在集合的相关方法中,凡是使用类的泛型的位置,都替换为具体的泛型类型
在比较器中使用泛型
定义Employee类
public class Employee implements Comparable<Employee>{
//定义一个Employee类
/*
该类包含 private 成员变量 name,age,birthday 其中birthday是MyData类的对象
并为每一个属性定义 getter setter方法
并重写toString方法 输出 name,age,birthday
*/
private String name;
private int age;
private MyDate birthday;
public Employee(){
}
public Employee(String name,int age,MyDate birthday){
this.age = age;
this.name = name;
this.birthday = birthday;
}
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;
}
public MyDate getBirthday() {
return birthday;
}
public void setBirthday(MyDate birthday) {
this.birthday = birthday;
}
@Override
public String toString() {
return "Employee{" +
"name='" + name + '\'' +
", age=" + age +
", birthday=" + birthday +
'}';
}
@Override
public int compareTo(Employee o) {
//按照name从高到低排序
return this.name.compareTo(o.name);
}
}
定义MyDate类
public class MyDate {
/*
MyDate类包换 year,month,day并为每一个属性定义 get set方法
*/
private int year;
private int month;
private int day;
public MyDate(){
}
public MyDate(int year,int month,int day){
this.year = year;
this.month = month;
this.day = day;
}
public void setYear(int year){
this.year = year;
}
public void setMonth(int month){
this.month = month;
}
public void setDay(int day){
this.day = day;
}
public int getYear(){
return this.year;
}
public int getMonth(){
return this.month;
}
public int getDay(){
return this.day;
}
@Override
public String toString() {
return year+"年" +month +"月" + day+"日";
}
}
测试
- 在Employee类上实现Comparable接口
- 创建TreeSet时,传入comparator方法
public class EmployeeTest {
//需求1 使Employee实现Comparable接口,并按name排序
@Test
public void test1(){
TreeSet<Employee> set = new TreeSet<>();
Employee e1 = new Employee("Han",18,new MyDate(1998,12,11));
Employee e2 = new Employee("LiLei",18,new MyDate(1998,12,11));
Employee e3 = new Employee("LiHua",18,new MyDate(1998,12,11));
Employee e4 = new Employee("ZhangSan",18,new MyDate(1998,12,11));
Employee e5 = new Employee("Alice",23,new MyDate(2001,12,11));
set.add(e1);
set.add(e2);
set.add(e3);
set.add(e4);
set.add(e5);
Iterator<Employee> iterator = set.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
}
//需求2,创建TreeSet时 传入Comparator对象,按照生日日期的先后进行排序
@Test
public void test2(){
Comparator<Employee> comparator= new Comparator<Employee>(){
@Override
public int compare(Employee o1, Employee o2) {
int yearDistance = o1.getBirthday().getYear() - o2.getBirthday().getYear();
if(yearDistance != 0 ){
return yearDistance;
}
int monthDistance = o1.getBirthday().getMonth() - o2.getBirthday().getMonth();
if(monthDistance != 0){
return monthDistance;
}
return o1.getBirthday().getDay() - o2.getBirthday().getDay();
}
};
TreeSet<Employee> set = new TreeSet<>(comparator);
//和上述需求1相同
}
}