泛型的由来:通过Object转型问题引入
早期的Object类型可以接收任意的对象类型,但是在实际的使用中,会有类型转换的问题。也就存在这隐患,所以Java提供了泛型来解决这个安全问题。
泛型好处
* 提高安全性(将运行期的错误转换到编译期)
* 省去强转的麻烦
泛型基本使用
* <>中放的必须是引用数据类型
* D:泛型使用注意事项
* 前后的泛型必须一致,或者后面的泛型可以省略不写(1.7的新特性菱形泛型)
import java.util.ArrayList;
import java.util.Iterator;
public class Test {
/**
* A:泛型概述
* B:泛型好处
* 提高安全性(将运行期的错误转换到编译期)
* 省去强转的麻烦
* C:泛型基本使用
* <>中放的必须是引用数据类型(对象)
* D:泛型使用注意事项
* 前后的泛型必须一致,或者后面的泛型可以省略不写(1.7以后的新特性菱形泛型)
*/
public static void main(String[] args) {
demo1();
//int[] arr = new byte[5]; //数组要保证前后的数据类型一致
//ArrayList<Object> list = new ArrayList<Person>(); //集合的泛型要保证前后的数据类型一致
//ArrayList<Object> list = new ArrayList<>(); //1.7版本的新特性,菱形泛型
ArrayList<Object> list = new ArrayList<>(); //泛型最好不要定义成Object,没有意义
list.add("aaa");
list.add(true);
}
public static void demo1() {
ArrayList<Person> list = new ArrayList<Person>();
// list.add(110);
// list.add(true);
list.add(new Person("aa", 3));
list.add(new Person("bb", 4));
Iterator<Person> it = list.iterator();
while(it.hasNext()) {
//System.out.println(it.next());
//System.out.println(it.next().getName() + " " + it.next().getAge());//next方法只能调用一次,如果调用多次会将指针向后移动多次
Person p = it.next();
System.out.println(p.getName() + " " + p.getAge());
}
}
}
class Person {
private String name;
private int age;
public Person() {
super();
}
public Person(String name, int age) {
super();
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 "Person [name=" + name + ", age=" + age + "]";
}
/*@Override
public boolean equals(Object obj) {
Person p = (Person)obj;
return this.name.equals(p.name) && this.age == p.age;
}*/
}
输出:
aa 3
bb 4
泛型类和泛型方法:
public class Test {
/**
* 泛型的由来:通过Object转型问题引入
* 早期的Object类型可以接收任意的对象类型,但是在实际的使用中,会有类型转换的问题。也就存在这隐患,所以Java提供了泛型来解决这个安全问题。
*/
public static void main(String[] args) {
demo1();
Tool<String> t = new Tool<>();
//t.show("abc");
t.show(true);//类型自动装箱
}
public static void demo1() {
Tool<Student> t = new Tool<Student>(); //创建工具类对象
t.setObj(new Student("aa",3));
System.out.println(t.getObj());
//Worker w = (Worker) t.getObj(); //向下转型
//System.out.println(w);
}
}
class Student extends Person {
public Student() {
}
public Student(String name, int age) {
super(name, age);
}
}
//泛型类
class Tool<Q> {
private Q q;
public Q getObj() {
return q;
}
public void setObj(Q q) {
this.q = q;
}
public<T> void show(T t) { //方法泛型最好与类的泛型一致
System.out.println(t); //如果不一致,需要在方法上声明该泛型
}
public static<W> void print(W w) { //静态方法必须声明自己的泛型
System.out.println(w);
}
}
class Worker extends Person {
public Worker() {
}
public Worker(String name, int age) {
super(name, age);
}
}
class Person {
private String name;
private int age;
public Person() {
super();
}
public Person(String name, int age) {
super();
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 "Person [name=" + name + ", age=" + age + "]";
}
/*@Override
public boolean equals(Object obj) {
Person p = (Person)obj;
return this.name.equals(p.name) && this.age == p.age;
}*/
}
输出:
Person [name=aa, age=3]
true
泛型接口:
public class Test {
/**
* * A:泛型接口概述
* 把泛型定义在接口上
* B:定义格式
* public interface 接口名<泛型类型>
*/
public static void main(String[] args) {
Inter<String> inter=new Demo<String>();
inter.show("123");
}
}
interface Inter<T> {
public void show(T t);
}
/*class Demo implements Inter<String> { //推荐用这种
@Override
public void show(String t) {
System.out.println(t);
}
}*/
class Demo<T> implements Inter<T> { //没有必要在实现接口的时候给自己的类加泛型(指定类型的类调用接口扩展功能)
@Override
public void show(T t) {
System.out.println(t);
}
}
输出:
123
通配符:
泛型固定上边界
* ? extends E
import java.util.ArrayList;
import java.util.List;
public class Test {
/**
* * A:泛型通配符<?>
* 任意类型,如果没有明确,那么就是Object以及任意的Java类了
* B:? extends E
* 向下限定,E及其子类
* C:? super E
* 向上限定,E及其父类
*/
public static void main(String[] args) {
//List<?> list = new ArrayList<Integer>(); //当右边的泛型是不确定时,左边可以指定为?
ArrayList<Person> list1 = new ArrayList<Person>();
list1.add(new Person("aa", 3));
list1.add(new Person("bb", 4));
list1.add(new Person("cc", 5));
ArrayList<Student> list2 = new ArrayList<Student>();
list2.add(new Student("dd", 6));
list2.add(new Student("ee", 7));
list1.addAll(list2);//addAll的参数为Collection<? extends E> c
//list2.addAll(list1);//错误,Student类为Person类的子类
System.out.println(list1);
}
}
class Person {
private String name;
private int age;
public Person() {
super();
}
public Person(String name, int age) {
super();
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 "Person [name=" + name + ", age=" + age + "]";
}
/*@Override
public boolean equals(Object obj) {
Person p = (Person)obj;
return this.name.equals(p.name) && this.age == p.age;
}*/
}
class Student extends Person {
public Student() {
}
public Student(String name, int age) {
super(name, age);
}
}
输出:
[Person [name=aa, age=3], Person [name=bb, age=4], Person [name=cc, age=5], Person [name=dd, age=6], Person [name=ee, age=7]]
泛型固定下边界
* ? super E
import java.util.ArrayList;
import java.util.Comparator;
import java.util.TreeSet;
public class Test {
/**
* 泛型固定下边界
* ? super E
*
* 泛型固定上边界
* ? extends E
*/
public static void main(String[] args) {
//demo1();
TreeSet<Student> ts1 = new TreeSet<>(new CompareByAge());
ts1.add(new Student("张三", 33));
ts1.add(new Student("李四", 13));
ts1.add(new Student("王五", 23));
ts1.add(new Student("赵六", 43));
TreeSet<BaseStudent> ts2 = new TreeSet<>(new CompareByAge());
ts2.add(new BaseStudent("张三", 33));
ts2.add(new BaseStudent("李四", 13));
ts2.add(new BaseStudent("王五", 23));
ts2.add(new BaseStudent("赵六", 43));
System.out.println(ts2);
}
public static void demo1() {
ArrayList<Student> list1 = new ArrayList<>();
list1.add(new Student("张三", 23));
list1.add(new Student("李四", 24));
ArrayList<BaseStudent> list2 = new ArrayList<>();
list2.add(new BaseStudent("王五", 25));
list2.add(new BaseStudent("赵六", 26));
list1.addAll(list2);
}
}
class CompareByAge implements Comparator<Student> {
@Override
public int compare(Student s1, Student s2) {
int num = s1.getAge() - s2.getAge();
return num == 0 ? s1.getName().compareTo(s2.getName()) : num;
}
}
class BaseStudent extends Student {
public BaseStudent() {
}
public BaseStudent(String name, int age) {
super(name, age);
}
}
class Student implements Comparable<Student> {
private String name;
private int age;
public Student() {
super();
}
public Student(String name, int age) {
super();
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 + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Student other = (Student) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
@Override
public int compareTo(Student o) {
int num = this.age - o.age; //以年龄为主要条件
return num == 0 ? this.name.compareTo(o.name) : num;
}
}
输出:
[Student [name=李四, age=13], Student [name=王五, age=23], Student [name=张三, age=33], Student [name=赵六, age=43]]