1.在集合中使用泛型
- 集合接口或集合类在jdk 5.0中都修改为带泛型的结构
- 在实例化集合类时,可以指明具体的泛型类型
- 指明完以后,在集合类或接口中凡是定义类或接口时,内部结构(比如方法、构造器、属性)使用到类的泛型位置,都指定为实例化时泛型类型。比如:add(E e)---->实例化以后:add(Integer e)
- 注意点:泛型的类型必须是类,不能是基本数据类型,需要用到基本数据类型的位置,拿包装类替换
- 如果实例化时没有指明泛型的类型,默认为Object类型
public class GenericTest {
//在集合中使用泛型之前的情况:
@Test
public void test1() {
ArrayList list = new ArrayList();
//需求:存放学生的成绩
list.add(78);
list.add(76);
list.add(92);
list.add(82);
//问题一:类型不安全
list.add("Tom");
//问题二:强转时,可能出现ClassCastException
for (Object score : list) {
int stuScore = (Integer) score;
System.out.println(stuScore);
}
}
//在集合中使用泛型的情况
@Test
public void test2() {
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(78);
list.add(76);
list.add(92);
list.add(82);
//编译时就会进行类型检查,保证数据的安全性
//list.add("Tom");
//方式一:
// for(Integer score:list){
// //避免了强制类型转换操作
// int stuScore = score;
// System.out.println(stuScore);
// }
//方式二:
Iterator<Integer> iterator = list.iterator();
while (iterator.hasNext()) {
int stuScore = iterator.next();
System.out.println(stuScore);
}
}
//在集合中使用泛型的情况:HashMap为例
@Test
public void test3() {
Map<String, Integer> map = new HashMap<String, Integer>();
//jdk7新特性:类型推断
//Map<String, Integer> map = new HashMap<>();
map.put("Tom", 84);
map.put("Jack", 95);
map.put("Jerry", 91);
Set<Map.Entry<String, Integer>> e = map.entrySet();
Iterator<Map.Entry<String, Integer>> iterator = e.iterator();
while (iterator.hasNext()) {
Map.Entry<String, Integer> next = iterator.next();
Integer value = next.getValue();
String key = next.getKey();
System.out.println(key + "---->" + value);
}
}
}
2.定义泛型结构
- 子类在继承带泛型的父类时,指明了泛型类型,则实例化子类对象时,不再需要指明泛型。
- 泛型方法,在方法中出现了泛型的结构,泛型参数与类的泛型参数没有任何关系,换句话说,泛型方法所属的类不是泛型类都没有关系。
- 泛型方法可以声明为静态的。原因:泛型参数是在调用方法时确定的,并非在实例化类时确定。
public class GenericTest1 {
@Test
public void tese1() {
//如果定义了泛型类,实例化没有指明类的泛型,则认为此泛型类型为Object类型
//要求:如果大家定义了类时带泛型的,建议在实例化时要指明类的泛型
//Order order = new Order();
//建议:实例化时指明类的泛型
Order<String> order1 = new Order<>("orderAA", 100, "hi");
Order<Integer> order2 = new Order<>("orderAA", 100, 123);
}
//测试泛型方法
@Test
public void test2() {
Order<String> order = new Order<>();
Integer[] arr = new Integer[]{1,2,3,4,};
List<Integer> integers = order.copyFromArrayToList(arr);
System.out.println(integers);
}
}
public class Order<T> {
private String name;
private int id;
private T orderT;
public Order() {
}
public Order(String name, int id, T orderT) {
this.name = name;
this.id = id;
this.orderT = orderT;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public T getOrderT() {
return orderT;
}
public void setOrderT(T orderT) {
this.orderT = orderT;
}
@Override
public String toString() {
return "Order{" +
"name='" + name + '\'' +
", id=" + id +
", orderT=" + orderT +
'}';
}
public <E> List<E> copyFromArrayToList(E[] arr){
ArrayList<E> list = new ArrayList<>();
for(E e:arr){
list.add(e);
}
return list;
}
}
泛型在继承方面的体现:
- 虽然类A是类B的父类,但是G< A >和G< B >二者不具备子父类关系,二者是并列关系。
- 类A是类B的父类,A< G >是B< G >的父类
3.通配符的使用
-
通配符:?
-
类A是类B的父类,G< A >和G< B >二者不具备子父类关系,二者的共同父类是:< ? >
-
有限制条件的通配符的使用
-
- ? extends A:
G<? extends A> 可以作为G< A >和G< B >的父类,其中B是A的子类
- ? extends A:
-
- ? super A:
G<? super A > 可以作为G< A >和G< B >的父类,其中B是A的父类
- ? super A:
public class GenericTest {
@Test
public void test1(){
List<Object> list1 = null;
List<String> list2 = null;
List<?> list = null;
list = list1;
list = list2;
// print(list1);
// print(list2);
List<String> list3 = new ArrayList<>();
list3.add("AA");
list3.add("BB");
list3.add("CC");
list = list3;
//添加:对于List<?>就不能向其内部添加数据
//除了添加null之外
//list.add("DD");
//list.add(null);
//获取(读取):允许读取数据,读取的数据类型为Object
Object o = list.get(0);
System.out.println(o);
}
public void print(List<?> list){
Iterator<?> iterator = list.iterator();
while (iterator.hasNext()){
Object next = iterator.next();
System.out.println(next);
}
}
}
4.泛型使用示例
/**
* @author Mr.Zhu
* @create 2020-07-17-16:28
*/
/*
定义一个User类:
该类包含:private成员变量(int类型)id,age;(String类型)name。
*/
public class User {
private int id;
private int age;
private String name;
public User() {
}
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 + '\'' +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return id == user.id &&
age == user.age &&
Objects.equals(name, user.name);
}
@Override
public int hashCode() {
return Objects.hash(id, age, name);
}
}
/**
* @author Mr.Zhu
* @create 2020-07-17-16:02
*/
/*
定义一个泛型类DAO<T>,在其中定义一个Map成员变量,Map的键为String类型,值为T类型。
分别创建一下方法:
public void save(String id, T entity):保存T类型的对象到Map成员变量中
public T get(String id):从map中获取id对应的对象
public void update(String id, T entity):替换map中key为id的内容,改为entity对象
public List<T> list():返回map中存放的所有T对象
public void delete(String id):删除指定id对象
*/
public class DAO<T> {
private Map<String, T> map = new HashMap<>();
//保存T类型的对象到Map成员变量中
public void save(String id, T entity) {
map.put(id, entity);
}
//从map中获取id对应的对象
public T get(String id) {
return map.get(id);
}
//替换map中key为id的内容,改为entity对象
public void update(String id, T entity) {
if (map.containsKey(id)) {
map.put(id, entity);
}
}
//返回map中存放的所有T对象
public List<T> list() {
List<T> list = new ArrayList<>();
Collection<T> values = map.values();
for (T t : values) {
list.add(t);
}
return list;
}
//删除指定id对象
public void delete(String id) {
map.remove(id);
}
}
/**
* @author Mr.Zhu
* @create 2020-07-17-16:32
*/
/*
创建DAO类的对象,分别调用其save、get、update、list、delete方法来操作User对象,使用Junit单元测试类进行测试
*/
public class DAOTest {
public static void main(String[] args) {
DAO<User> dao = new DAO<>();
dao.save("1001",new User(1001,34,"周杰伦"));
dao.save("1002",new User(1002,20,"昆凌"));
dao.save("1003",new User(1003,25,"蔡依林"));
List<User> list = dao.list();
System.out.println(list);
dao.update("1003",new User(1003,30,"方文山"));
List<User> list1 = dao.list();
System.out.println(list1);
dao.delete("1002");
List<User> list2 = dao.list();
System.out.println(list2);
}
}