Java当中泛型的简单使用

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.定义泛型结构

  1. 子类在继承带泛型的父类时,指明了泛型类型,则实例化子类对象时,不再需要指明泛型。
  2. 泛型方法,在方法中出现了泛型的结构,泛型参数与类的泛型参数没有任何关系,换句话说,泛型方法所属的类不是泛型类都没有关系。
  3. 泛型方法可以声明为静态的。原因:泛型参数是在调用方法时确定的,并非在实例化类时确定。
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的子类
    • ? super A:
      G<? super A > 可以作为G< A >和G< B >的父类,其中B是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);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值