1.练习回顾
public class Test {
public static void main(String[] args) {
List<Student> list = new LinkedList<>();
list.add(new Student("A01","xxx1",19));
list.add(new Student("A01","xxx2",17));
list.add(new Student("A01","xxx3",18));
list.add(new Student("A02","xxx4",19));
list.add(new Student("A02","xxx5",20));
Map<String,String> map = new HashMap<>();
Iterator<Student> it = list.iterator();
while (it.hasNext()){
Student s = it.next();
if (map.containsKey(s.getClas())){
map.put(s.getClas(),map.get(s.getClas())+","+s.getName());
continue;
}
map.put(s.getClas(),s.getName());
}
Iterator<String> it1 = map.keySet().iterator();
while (it1.hasNext()){
String s = it1.next();
System.out.println(s+"--->"+map.get(s));
}
}
}
public class Student {
private String clas;
private String name;
private int age;
public Student(String clas, String name, int age) {
this.name = name;
this.clas = clas;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getClas() {
return clas;
}
public void setClas(String clas) {
this.clas = clas;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", clas='" + clas + '\'' +
", age=" + age +
'}';
}
}
Hash Map:
2.泛型具体内容
2.1 泛型产生的意义
泛型是在JDK1.5之后增加的新功能,
意义:保证数据的安全性;
基本使用:由外部指定其具体的操作类型。
2.2 使用泛型类
(设计一个坐标点的类,坐标由X和Y组成,x,y的取值可以时数字,小数和字符串);在这样的需求下,可以使用泛型类来进行设计。
public class Position<T> {
private T x;
private T y;
//构造方法的参数使用泛型
public Position(T x, T y) {
this.x = x;
this.y = y;
}
public T getX() {
return x;
}
public void setX(T x) {
this.x = x;
}
public T getY() {
return y;
}
public void setY(T y) {
this.y = y;
}
@Override
public String toString() {
return "Position{" +
"x=" + x +
", y=" + y +
'}';
}
}
在泛型类中同时指定多个类型
public class Notepad<K,V>{
private K key;
private V value;
public Notepad(K key,V value){
this.key = key;
this.value = value;
}
public K getKey() {
return key;
}
public void setKey(K key) {
this.key = key;
}
public V getValue() {
return value;
}
public void setValue(V value) {
this.value = value;
}
@Override
public String toString() {
return "Notepad{" +
"key=" + key +
", value=" + value +
'}';
}
}
2.3 泛型擦除
Java中的泛型只在源码中存在,编译的时候静态地检查一下泛型类型是否正确;在运行时,Java不会保留泛型。
public static void main(String[] args) {
List<Integer> list = new LinkedList<>();
list.add(123);
list.add(321);
//list.add("aaa");
//泛型被擦除
List list2 = list;
list2.add("aaa");
list2.add("ccc");
System.out.println(list);
}
目的:
为了向下兼容,在Java 5 才引入泛型,引入泛型是为了解决遍历集合的时候总要手动强制转型的问题。
2.4 泛型通配符 ?
在程序开发中对象的引用传递是最常见的,但是如果方法参数是泛型类对象,则传入的泛型数据必须匹配才可以,否则无法传递。
public class Test {
public static void main(String[] args) {
Info<String> i = new Info<>();
i.setVar("wen");
//泛型类型不一致,报错
//fun(i);
}
public static void fun(Info<Object> info){
System.out.println(info);
}
}
一个类的子类可以通过对象多态化,为其父类实例化,但在泛型操作中,子类的泛型类型无法使用父类的泛型类型接受。
如果方法的参数没有指定泛型的时候,可以是使用擦除泛型的特性传递参数。
public static void fun(Info info){
System.out.println(info);
}
使用 ? 通配符设置泛型类型,接受泛型参数。
public static void fun(Info<?> info){
System.out.println(info);
//使用通配符 ? 可以接受任意泛型参数,但是此时是泛型对象不能修改数据
//info.setVar("mu");
}
2.5 受限泛型
在引用传递的过程中,泛型操作也可以设置一个泛型对象的范围上限和范围下限,范围上限使用extends关键字声明,表示参数化的类型可能是所指的类型,或者此类型的子类,而范围下限使用super进行声明,表示参数化的类型可能是所指的类型,或者此类型的父类型,直至Object类型。
2.5.1 设置泛型上限
public static void main(String[] args) {
Info<Integer> i1 = new Info<>();
i1.setVar(100);
fun(i1);
Info<Double> i2 = new Info<>();
i2.setVar(12.13);
fun(i2);
}
//设置范围上限是Number,只能接受数字类型
public static void fun(Info<? extends Number> info){
System.out.println(info);
}
//也可以直接定义在类里,设置好泛型范围
public class Info<T extends Number> {
private T var;
public T getVar(){
return var;
}
public void setVar(T var){
this.var = var;
}
@Override
public String toString() {
return "Info{" +
"var=" + var +
'}';
}
}
2.5.2 设置泛型下限
使用泛型只能在本类及其父类类型上应用的时候,就必须使用泛型的范围下限配置。(不能再定义类的时候使用下限定义,只能用?方式定义)
public class Test1 {
public static void main(String[] args) {
Info<String> i1 = new Info<>();
i1.setVar("wen");
fun(i1);
Info<Object> i2 = new Info<>();
i2.setVar("mu");
fun(i2);
}
public static void fun(Info<? super String> info){
System.out.println(info);
}
}
2.6 泛型方法
针对某个方法设置泛型
public class Info2 {
//泛型方法,无返回值
public <T> void test(T val){
System.out.println(val);
}
//返回字符串的泛型方法
public <T> String test2(T val){
return val.toString();
}
//返回任意类型的泛型方法
public <T> T test3(T val){
return val;
}
}