package com.atguigu.java;
import org.junit.Test;
import java.util.*;
/**
*
* 泛型的使用
* 1.jdk5.0新增的特性
* 2.在集合中使用泛型
* 总结:
* ①集合接口或者集合类在jdk5.0时都修改为带泛型的结构
* ②在实例化集合类时,可以指明具体的泛型类型
* ③指明完以后,在集合类或者接口中凡是定义类或接口时,内部结构(方法、构造器、属性)使用到泛型的位置,都指定为实例化的泛型类型
* 比如:add(E e)--->实例化以后:add(Integer e)
* ④注意点:泛型的类型必须是一个类,不能是基本数据类型,需要用到基本数据类型的位置,拿包装类替换
* ⑤如果实例化没有指明泛型的类型,默认类型为java.lang.Object类型
*
* @author
* @create 2022-04-24-9:41
*/
public class GenericTest {
//在集合中使用泛型之前的情况
@Test
public void test(){
ArrayList list = new ArrayList();
//需求:存放学生成绩
list.add(78);
list.add(76);
list.add(98);
list.add(45);
//问题一:类型不安全
// list.add("Tom");
for (Object score:list){
//问题二:强转时,可能出现ClassCastException
int stuScore= (int) score;
System.out.println(stuScore);
}
}
//在集合中使用泛型的情况(以ArrayList为例):
// 泛型是一个类型,不能使用基本数据类型,需要使用其包装类
@Test
public void test1(){
ArrayList<Integer> list1 = new ArrayList<>();
list1.add(12);
list1.add(23);
list1.add(78);
//编译时就会进行类型检查,保证数据安全
// list1.add("Tom");
//方式一:
// for (Integer score:list1){
// int stuScore=score;
// System.out.println(stuScore);
// }
//方式二:
Iterator<Integer> iterator = list1.iterator();
while (iterator.hasNext()){
int stuScore = iterator.next();
System.out.println(stuScore);
}
}
//在集合中使用泛型的情况(以HashMap为例):
@Test
public void test2(){
// HashMap<String, Integer> map = new HashMap<String, Integer>();
//jdk7新特性:类型推断
HashMap<String, Integer> map = new HashMap<>();
map.put("Tom",89);
map.put("Jerry",98);
map.put("Jack",78);
map.put("Rose",75);
//泛型的嵌套
Set<Map.Entry<String, Integer>> entry = map.entrySet();
Iterator<Map.Entry<String, Integer>> iterator = entry.iterator();
while (iterator.hasNext()){
Map.Entry<String, Integer> e = iterator.next();
String key = e.getKey();
Integer value = e.getValue();
System.out.println(key+"--->"+value);
}
}
}
package com.atguigu.java;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
/**3.如何自定义泛型结构:泛型类、泛型接口;泛型方法
* @author
* @create 2022-04-24-14:54
*/
public class GenericTest1 {
@Test
public void test(){
//如果定义了泛型类,实例化时没有指明类的泛型,则认为此泛型类型为Object类型
//要求:如果定义了类是带泛型的,建议实例化时要指明类的泛型
Order order = new Order();
order.setOrderT(123);
order.setOrderT("AA");
//建议:实例化时指明类的泛型
Order<String> order1 = new Order<>("orderAA",12,"order:AA");
order1.setOrderT("AA:hello");
}
@Test
public void test1(){
SubOrder subOrder = new SubOrder();
//由于子类继承带泛型的父类时,指明了泛型类型,则实例化子类对象时,不再需要指明泛型
subOrder.setOrderT(123);
SubOrder1<String> sub2 = new SubOrder1<>();
sub2.setOrderT("order2...");
}
@Test
public void test2(){
ArrayList<String> list1=null;
ArrayList<Integer> list2=null;
//泛型不同的引用不能相互赋值
// list1=list2;
}
//测试泛型方法
@Test
public void test3(){
Order<String> order =new Order<>();
Integer[] arr=new Integer[]{1,2,3,4};
List<Integer> list = order.copyFromArrayToList(arr);
System.out.println(list);
}
}
package com.atguigu.java;
import java.util.ArrayList;
import java.util.List;
/**自定义泛型类
* @author
* @create 2022-04-24-14:48
*/
public class Order<T> {
String orderName;
int orderId;
//类的内部结构就可以使用类的泛型
T orderT;
public Order(){
//编译不通过
// T[] arr=new T[];
//编译通过
T[] arr= (T[]) new Object[10];
}
public Order(String orderName,int orderId,T orderT){
this.orderName=orderName;
this.orderId=orderId;
this.orderT=orderT;
}
//如下的三个方法都不是泛型方法
public T getOrderT(){
return orderT;
}
public void setOrderT(T orderT){
this.orderT=orderT;
}
@Override
public String toString() {
return "Order{" +
"orderName='" + orderName + '\'' +
", orderId=" + orderId +
", orderT=" + orderT +
'}';
}
//静态方法中不能使用类的泛型
// public static void show(T orderT){
// System.out.println(orderT);
// }
//泛型方法:在方法中出现了泛型的结构,泛型参数与类的泛型参数没有任何关系
//即:泛型方法所属的类是不是泛型类都没有关系
//泛型方法可以声明为静态的。原因:泛型参数是在调用方法时确定的,并非实例化类时确定的。
public static <E> List<E> copyFromArrayToList(E[] arr){
ArrayList<E> list=new ArrayList<>();
for (E e:arr) {
list.add(e);
}
return list;
}
}
package com.atguigu.java;
/**
* @author
* @create 2022-04-24-15:00
*/
public class SubOrder extends Order<Integer>{//SubOrder1不再是泛型类
}
package com.atguigu.java;
/**
* @author
* @create 2022-04-24-15:03
*/
public class SubOrder1<T> extends Order<T>{//SubOrder1<T>仍然是泛型类
}