Java基础第8篇:泛型

文章目录

  • 一、为什么要有泛型?
  • 二、泛型的使用
    • 1.在集合中没有使用泛型的情况下
    • 2.在集合中使用泛型
    • 3.自定义泛型
    • 4.泛型与继承的关系
    • 5.通配符
    • 6.泛型的使用
    • 7.注意

一、为什么要有泛型?

1.解决元素存储的安全性问题

2.解决获取数据元素时,需要类型强转的问题

二、泛型的使用

1.在集合中没有使用泛型的情况下

    /**
     * 在集合中没有使用泛型的情况下
     */
    @Test
    public void test1() {
        List list = new ArrayList();
        list.add(65);
        list.add(89);
        list.add(78);
        //1.没有使用泛型,任何Object及其子类的对象都可以添加进来
        list.add(new String("AA"));
        for (int i = 0; i < list.size(); i++) {
            //2.获取元素的时候,需要强转int可能会出现java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
            int score = (Integer) list.get(i);
            System.out.println(score);
        }
    }

2.在集合中使用泛型

    /**
     * 在集合中使用泛型,解决类型转换问题和数据存储不安全性问题
     */
    @Test
    public void test2() {
        List<Integer> list = new ArrayList<Integer>();
        list.add(65);
        list.add(89);
        list.add(78);
        //list.add("AA");
//        for (int i = 0; i < list.size(); i++) {
//            int score = list.get(i);
//            System.out.println(score);
//        }
        Iterator<Integer> iterator = list.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }

    @Test
    public void test3() {
        Map<String, Integer> map = new HashMap<String, Integer>();
        map.put("AA", 89);
        map.put("BB", 67);
        map.put("CC", 90);
        Set<Map.Entry<String, Integer>> entry = map.entrySet();
        for (Map.Entry en : entry) {
            System.out.println("key==:" + en.getKey());
            System.out.println("value==:" + en.getValue());
        }

//        for (String key : map.keySet()) {
//            System.out.println(key);
//        }
//        for (Integer value : map.values()) {
//            System.out.println(value);
//        }

//   Iterator> iterator =  map.entrySet().iterator();
//   while (iterator.hasNext()){
//      Map.Entry integerEntry = iterator.next();
//       System.out.println(integerEntry.getKey());
//       System.out.println(integerEntry.getValue());
//   }

    }

3.自定义泛型

1.泛型类

package com.generic;

import java.util.ArrayList;
import java.util.List;

/**
 * 自定义泛型类
 */
public class Order<T> {

    private String orderName;

    private int orderId;

    private T t;

    public List<T> list = new ArrayList<>();

    public void add() {
        list.add(t);
    }


    public String getOrderName() {
        return orderName;
    }

    public void setOrderName(String orderName) {
        this.orderName = orderName;
    }

    public int getOrderId() {
        return orderId;
    }

    public void setOrderId(int orderId) {
        this.orderId = orderId;
    }

    public T getT() {
        return t;
    }

    public void setT(T t) {
        this.t = t;
    }

    @Override
    public String toString() {
        return "Order{" +
                "orderName='" + orderName + '\'' +
                ", orderId=" + orderId +
                ", t=" + t +
                '}';
    }
}

    /**
     * 自定义泛型类
     */
    @Test
    public void test4(){
        //1.当实例化泛型类的对象时,指明泛型的类型。
        //指明以后对应的类中所有使用泛型的位置,都变为实例化中指定的泛型的类型。
        //2.如果我们自定义了泛型类,但是在实例化的时候没有使用,默认是Object类型
        Order<Boolean> order = new Order<Boolean>();
        order.setT(true);
        System.out.println(order.getT());
        order.add();
        List<Boolean> list = order.list;
        System.out.println(list);

        SubOrder subOrder = new SubOrder();
        List<Integer> list1 = subOrder.list;
        System.out.println(list1);
    }

    /**
     * 继承泛型类或接口时,可以指明泛型的类型
     */
    class SubOrder extends Order<Integer>{

    }

    /**
     * 类似于list继承collection接口
     * @param 
     */
    class  SubOrder2<T> extends Order<T>{

    }

2.泛型接口

泛型接口与泛型类类似

3.泛型方法

    /**
     * 声明泛型方法
     * @param e
     * @param 
     * @return
     */
    public <E> E  getE(E e){
        return e;
    }
    /**
     * 实现数组到集合的复制
     * T[] toArray(T[] a);
     * @param e
     * @param 
     * @return
     */
    public <E> List<E> toArray(E[] e, List<E> list) {
        for (E e1 : e) {
            list.add(e1);
        }
        return list;
    }

    /**
     * 泛型方法的使用测试
     */
    @Test
    public void genericMethodTest(){
        Order<Integer> order = new Order<>();
        //当通过对象调泛型方法时,指明泛型方法的类型
        String s = order.getE("4");
        System.out.println(s);
        //将数组的元素复制到集合中
        Integer[] a = new Integer[]{2,3};
        List<Integer> list = new ArrayList<>();
        List<Integer> li = order.toArray(a,list);
        System.out.println(li);
    }

4.泛型与继承的关系

   /**
     * 泛型与继承的关系
     * 若类A是类B的子类,那么List不是List的子接口
     */
    @Test
    public void extendsTest(){
        Object obj = null;
        String str = "AA";
        obj = str;

        Object [] obj1= null;
        String [] str1 = new String[]{"AA","BB","CC"};
        obj1 = str1;

        List<Object> list = null;
        List<String> list1 = new ArrayList<String>();
        //list = list1;
        //反正法:假设list = list1满足
        //list.add(10);
        //String str = list1.get(0);//出现问题假设不满足,添加的是Integer类型取出的是String类型
        //泛型就是为了限制集合中元素的类型
    }

5.通配符

    /**
     * 通配符 ?
     * List、List。。等都是List< ?>的子类
     * 

* boolean addAll(Collection c); * ? extends A : 可以存放A及其子类 *

* ? supper A:可以存放及其父类 */ @Test public void commonTest() { List<?> list = null; List<Object> objectList = new ArrayList<>(); list = objectList; List<String> stringList = new ArrayList<>(); list = stringList; //只能存放Object类型的集合 show(objectList); //show(stringList);//报错 //任何类型的集合都可以存放,因为使用了通配符List show1(objectList); show1(stringList); } public void show(List<Object> li) { } //使用通配符 public void show1(List<?> li) { } /** * boolean addAll(Collection c); * * ? extends A : 可以存放A及其子类 * ? supper A :可以存放A及其父类 */ @Test public void commonExtendsTest() { List<? extends Number> list = null; List<Integer> list1 = new ArrayList<>(); List<Object> list3 = new ArrayList<>(); list = list1; //list = list2;报错 List<? super Number> listSuper = null; listSuper = list3; }

通配符的使用

    /**
     * 通配符的使用
     */
    @Test
    public void commentUseTest() {
        List<String> stringList = new ArrayList<>();
        stringList.add("aa");
        stringList.add("bb");
        List<?> list = null;
        list = stringList;
        //可以声明读取通配符的集合类的对象
        Iterator<?> iterator = list.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
        //不允许向声明为通配符的集合类中写入对象,唯一例外的是可以存放null
//        list.add("cc");
//        list.add("dd");
        list.add(null);
    }

6.泛型的使用

package com.generic;

import org.omg.CORBA.OBJ_ADAPTER;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * DataBase access object 数据库访问对象
 *
 *
 * 定义个泛型类 DAO,在其中定义一个Map 成员变量,Map 的键为 String 类型,值为 T 类型。
 *
 * 分别创建以下方法:
 * public void save(String id,T entity): 保存 T 类型的对象到 Map 成员变量中
 * T get(String id):从 map 中获取 id 对应的对象
 * void update(String id,T entity):替换 map 中key为id的内容,改为 entity 对象
 * List list():返回 map 中存放的所有 T 对象
 * void delete(String id):删除指定 id 对象
 * @param 
 */
public class DAO<T> {

    Map<String,T> map = new HashMap<String,T>();

    public  void saveUser(String id,T t){
        map.put(id,t);
    }

    public T getUser(String id){
        return map.get(id);
    }

    public void updateUser(String id,T t){
        map.put(id,t);
    }

    public List<T> getListUser(){
        List<T> li = new ArrayList<>();
        for (Map.Entry<String,T> entry : map.entrySet()){
            li.add(entry.getValue());
        }
        return  li;
    }

    public void deleteUser(String id){
        map.remove(id);
    }
    public void add(T t) {
    }

    public T get(int index) {
        return null;
    }

    public List<T> getForList(int index) {
        return null;
    }

    public void delete(int index) {

    }
}

测试

/**
 * 测试DAO泛型的方法
 */
public class UserTestDao {

    @Test
    public void userDaoTest(){
        DAO<User> userDAO = new DAO<>();
        User user = new User();
        user.setId(1);
        user.setAge(12);
        user.setName("胡歌");
        User user1 = new User();
        user1.setId(2);
        user1.setAge(34);
        user1.setName("胡军");
        userDAO.saveUser("1001",user);
        userDAO.saveUser("1002",user1);
        User u = userDAO.getUser("1001");
        System.out.println(u);
        user1.setName("刘德华");
        userDAO.updateUser("1001",user);
        List<User> list = userDAO.getListUser();
        System.out.println(list);
    }
}

7.注意

泛型规定了集合中只能存放特定类型的对象
对于泛型类包含集合类注意以下几点:
静态方法中不能使用类的泛型
如果泛型类是一个或者抽象类,不可以创建泛型类的对象
不能在cath中使用泛型
从泛型类派生子类,泛型类型需具体化

你可能感兴趣的:(Java基础,java)