泛型的使用
在集合中使用泛型
-
集合接口或集合类在jdk5.0时都修改为带泛型的结构
-
在实例化集合类时,可以指明具体的泛型类型
-
指明完以后,在集合类或接口中凡是定义类或接口时,内部结构使用泛型的位置,都指定为实例化时泛型的类型(比如:add(E e)---->实例化以后:add(Integer e))
-
泛型的类型必须是类,不能是基本数据类型。
p.567
package com.yicurtain.SETS;
import org.junit.Test;
import java.sql.Array;
import java.util.*;
public class GenericTest {
@Test
public void test1(){
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(78);
list.add(87);
list.add(88);
list.add(89);
// 因为使用了泛型,所以只允许添加Integer类型的数据
// list.add("TOM")
// 方式一 使用增强for循环
// for (Integer score:list
// ) {
// System.out.println(score);
// }
// 方式二 使用迭代器的方式
Iterator<Integer> iterator = list.iterator();
while (iterator.hasNext()){
Integer next = iterator.next();
System.out.println(next);
}
}
@Test
public void test3(){
HashMap<String, Integer> map = new HashMap<>();
map.put("Jerry",87);
map.put("Hery",78);
map.put("Jack",77);
map.put("Rose",89);
Set<Map.Entry<String, Integer>> entry = map.entrySet();
Iterator<Map.Entry<String, Integer>> iterator = entry.iterator();
while (iterator.hasNext()){
Map.Entry<String, Integer> next = iterator.next();
String key = next.getKey();
Integer value = next.getValue();
System.out.println("集合:"+next+",键:"+key+",值:"+value);
}
}
}
自定义泛型类
- public class Order
{} ----->Order类就具备了泛型的特性 - 由于子类在继承带泛型的父类时,父类指明了泛型的类型,则实例化子类的对象时,不再需要指明泛型(相当于泛型具有继承性)
注意点
-
泛型类可能有多个参数,此时应将多个参数一起放在尖括号内。比如:
<E1,E2,E3> -
泛型类的构造器如下:public GenericClass(){}。
而下面是错误的:public GenericClass(){} -
实例化后,操作原来泛型位置的结构必须与指定的泛型类型一致。
-
泛型不同的引用不能相互赋值
- 尽管在编译时ArrayList
和ArrayList 是两种类型,但是,在运行时只有
一个ArrayList被加载到JVM中。
- 尽管在编译时ArrayList
-
泛型如果不指定,将被擦除,泛型对应的类型均按照Object处理,但不等价
于Object。经验:泛型要使用一路都用。要不用,一路都不要用。 -
如果泛型结构是一个接口或抽象类,则不可创建泛型类的对象。
-
jdk1.7,泛型的简化操作:ArrayList
flist = new ArrayList<>(); -
泛型的指定中不能使用基本数据类型,可以使用包装类替换。
-
在类/接口上声明的泛型,在本类或本接口中即代表某种类型,可以作为非静态
属性的类型、非静态方法的参数类型、非静态方法的返回值类型。但在静态方法
中不能使用类的泛型。 -
异常类不能是泛型的
-
不能使用new E[]。但是可以:E[] elements = (E[])new Object[capacity];
参考:ArrayList源码中声明:Object[] elementData,而非泛型参数类型数组。 -
父类有泛型,子类可以选择保留泛型也可以选择指定泛型类型:
子类不保留父类的泛型:按需实现
没有类型 擦除
具体类型
子类保留父类的泛型:泛型子类
全部保留
部分保留
结论:子类必须是“富二代”,子类除了指定或保留父类的泛型,还可以增加自
己的泛型
泛型方法
- 在方法中出现了泛型的结构,泛型参数与类的泛型参数没有任何关系
- 泛型方法可以声明为静态的。原因:泛型参数在调用方法时是确定的,并非在实例化时确定。
泛型在继承方面的体现
- 类A是类B的父类,但是G、G不具备子父类关系,二者是并列关系。
- 类A是类B的父类,那么A
也是B 的父类。
通配符的使用
-
通配符:“?”
-
类A是类B的父类,但是G、G不具备子父类关系;二者共同的父类:G<?>.
-
有限制条件的通配符的使用
- (无穷小 , Number] 只允许泛型为Number及Number子类的引用调用
- [Number , 无穷大) 只允许泛型为Number及Number父类的引用调用
练习
package com.yicurtain.Generic;
import java.util.*;
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(){
ArrayList<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);
}
}
package com.yicurtain.Generic;
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 int getAge() {
return age;
}
public String getName() {
return name;
}
public void setId(int id) {
this.id = id;
}
public void setAge(int age) {
this.age = age;
}
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;
if (id != user.id) return false;
if (age != user.age) return false;
return name != null ? name.equals(user.name) : user.name == null;
}
@Override
public int hashCode() {
int result = id;
result = 31 * result + age;
result = 31 * result + (name != null ? name.hashCode() : 0);
return result;
}
}
package com.yicurtain.Generic;
import java.util.Iterator;
import java.util.List;
public class GenericTest {
public static void main(String[] args) {
DAO<User> dao = new DAO<>();
dao.save("1001",new User(1001,25,"周杰伦"));
dao.save("1002",new User(1002,18,"昆凌"));
dao.save("1003",new User(1003,25,"方文山"));
dao.update("1003",new User(1003,19,"蔡依林"));
dao.delete("1003");
List<User> list = dao.list();
Iterator<User> iterator = list.iterator();
while(iterator.hasNext()){
User next = iterator.next();
System.out.println(next);
}
}
}
浙公网安备 33010602011771号