赤赤赤赤辰

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

Java泛型笔记参考

Java泛型

image-20210602190434323

image-20210602190441486

每日一考

  • 如何遍历Map的key类,value类,key-value类,使用泛型
Map<String,Integer> map = new HashMap<String,Integer>();
map.put();..
    //遍历key
Set<String> keySet = map.keySet();
for(String key:keySet)
{
    sout(key);
}
//遍历value
Collection<Integer> values = map.values()l
Iterator<Integer> iterator = values.iterator();
while(iterator.hasNext()){
    sout(iterator.next());
}

//遍历key-value
//Set的泛型是Map.Entry
//entry的泛型是<String,Integer>
Set<Map.Entry<String,Integer>> set = map.entrySet();
Iterator<Map.Entry<String,Integer>> it = set.iterator<Map.Entry<String,Integer>>();
while(it.hasNext()){
    Map.Entry entry = it.next();
    String key = entry.getKey();
    Integer value = entry.getValue();
}
  • 创建一个与a.txt文件同目录下的另外一个文件b.txt
File f1 = new File("d:\\a\\a.txt");
File f2 = new File(file1.getParent(),"b.txt");
  • Map接口中的常用方法
增:put(K k,V v)
删:V remove(K k)
改:put(K k,V v)
查:V get(K k)
长度:int size()
遍历:

复习

泛型的理解

  • 泛型的概念
    • 所谓泛型,就是允许在定义类、接口时通过一个标识表示类中某个属性的类 型或者是某个方法的返回值及参数类型。这个类型参数将在使用时(例如, 继承或实现这个接口,用这个类型声明变量、创建对象时)确定(即传入实 际的类型参数,也称为类型实参)
  • 泛型的引入

泛型在集合中的使用

image-20210604204328316

public class GenericTest {
    @Test
    public void test1(){
        ArrayList list = new ArrayList();
        list.add(12);
        list.add(99);
        //问题一:类型不安全
        list.add("Tom");
        for(Object item:list){
            //Object-强转-》Integer-自动装箱-》int
            //java.lang.String cannot be cast to java.lang.Integer
            int score = (Integer) item;
            System.out.println(score);
        }
    }

image-20210604204335457

    //集合中使用泛型的情况,以HashMap为例
    @Test
    public void test3(){
        HashMap<String,Integer> map = new HashMap<String,Integer>();
        map.put("Tom",12);
        map.put("pp",90);
//        map.entrySet();
        //泛型的嵌套 Set<E> Map.Entry<K,E>
        Set<Map.Entry<String,Integer>> entry = map.entrySet();
        Iterator<Map.Entry<String,Integer>> it= entry.iterator();
        while(it.hasNext()){
            Map.Entry<String,Integer> e = it.next();
            System.out.println(e.getKey()+"->"+e.getValue());
        }
    }
  • 集合中使用泛型总结
/**
 * 泛型的使用
 * 1. jdk5.0新增的特性
 * 2. 在集合中使用泛型
 *  总结:
 *      ①集合接口或者集合类在jdk5.0时都修改为带泛型的结构
 *      ②在实例化集合类时,可以指明具体的泛型类型
 *      ③指明完以后,在集合类或接口中凡是定义类或接口时,内部结构(比如方法,构造器,属性)只用到类的泛型的位置,都指定为实例化的泛型类型.
 *      比如add(E e) --> 实例化以后:add(Integer e)
 *      ④ 注意点:泛型的类型必须是类,不能是基本数据类型,需要用到基本数据类型的位置,都用包装类.
 *      ⑤如果实例化时,没有指明泛型的类型,默认类型为java.lang.Object
 * 3. 如何自定义范型结:泛型类,泛型接口;泛型方法。见GenericTest1
 * @author shc
 * @create 2021-06-02 14:30
 */

自定义泛型类

/**
 * 自定义的泛型类
 * 1.
 * @author shc
 * @create 2021-06-02 18:22
 */
public class Order <T>{
    String name;
    int id;
    //类的内部结构可以使用类的泛型
    T ordert;

    public void method(){
        //编译不通过
        //new的话得是一个类,T在这里是一个参数而非类
//        T[] arr = new T[10];
        //编译通过.但要注意传入的Object[0,1,2,3...]都必须是T类型的
        T[] arr = (T[])new Object[10];
    }

    public Order(){}
    //如下三个方法都不是泛型方法
    public Order(String name,int id,T ordert){
        this.name = name;
        this.id = id;
        this.ordert = ordert;
    }
    public T getOrdert(){
        return this.ordert;
    }
    public void setOrdert(T ordert){
        this.ordert = ordert;
    }
    //静态方法中给不能使用泛型,因为泛型是在实例化对象时才确定的。不属于类
//    public static void f(T ordert){
//        ordert = null;
//    }

    //泛型方法:在方法中,出现了泛型的结构,泛型参数与类的泛型参数没有任何关系
    //换句话说,泛型方法所属的类是不是泛型都没关系
    //public后面有个<E>是为了告诉编译器,E不是一个类,而是一个泛型参数
    //泛型方法可以声明为static的。原因:泛型参数是在调用方法时确定的,并非在实例化时确定的。
    public static <E> List<E> copyFromArrayToList(E[] arr){
        ArrayList<E> list = new ArrayList<E>();
        for(E item:arr){
            list.add(item);
        }
        return list;
//        list = (ArrayList<E>) Arrays.asList(arr);
    }


}

//SubOrder是一个普通类,不再是一个泛型类
public class SubOrder extends Order<Integer>{

}

//实例化时,如下代码是错误的
SubOrder<Integer> o = new SubOrder<>();
//SubOrder1仍然是一个泛型类public class Suborder1<T> extends Order<T>{}
/** * 如何自定义范型结构、泛型类、泛型接口、泛型方法 * 1. 关于自定义泛型类,泛型接口 *  * @author shc * @create 2021-06-02 18:25 */public class GenericTest1 {    @Test    public void test1(){        //如果定义了泛型类,实例化没有指明类的泛型。则认为此泛型类型为Object类.        //要求:如果大家定义了类是带泛型的,建议在实例化时要指明类的泛型        Order order = new Order();        order.setOrdert(123);        order.setOrdert("ABC");        System.out.println(order.ordert);        //建议:实例化时,指明类的泛型        Order<String> order1 = new Order<String>("hh",45,"cnm");        order1.setOrdert("AA:Bye");    }    @Test    public void test2(){        SubOrder sub1 = new SubOrder();        //由于子类在继承带泛型的父类时,指明了泛型类型。则实例化子类对象时,不再需要指明泛型        sub1.setOrdert(45);        //泛型类Suborder1        Suborder1<String> sub2 = new Suborder1<String>();        sub2.setOrdert("AAAA");    }    //测试泛型方法    @Test    public void test3(){        Order<String> order = new Order<String>();        Integer[] arr = new Integer[]{1,2,3,4};        List<Integer> list = order.copyFromArrayToList(arr);        System.out.println(list);    }}

image-20210604205825299

  • 应用场景
  • ORM思想:Java中的一个类对应于数据库中的一个表
public class Customer {}
//专门用于操作Customer表public class CustomerDAO extends DAO<Customer>{}
package com.shc.java2;import java.util.List;/** * DAO:data(base) access object * 操作数据库的通用操作 * @author shc * @create 2021-06-02 19:26 */public class DAO <T>{    //添加一条记录    public void add(T t){ }    //删除一条记录    public boolean reomve(int idx){        return false;    }    //修改一条记录    public void update(int idx,T t){ }    //查询一条记录    public T getT(int idx){return null;}    //查询多条记录    public List<T> getForList(int idx){        return null;    }    //泛型方法:    public <E> E getValue(){        return null;    }}
public class DAOTest {    @Test    public void test1(){        CustomerDAO dao1 = new CustomerDAO();        dao1.add(new Customer());        List<Customer> list = dao1.getForList(10);    }}

泛型&继承

 /*    1. 泛型在继承方面的体现    类A是类B的父类,G<A> 和 G<B> 不具备子父类关系。二者并列关系    补充:类A是类B的父类,A<G>是B<G>的父类     */    @Test    public void test1(){        List<Object> list1 = null;        List<String> list2 = null;//        list2 = list1; list1和list2不具有子父类关系        //如果构成了子父类关系,则意味着list1可以管理list2,那么list2本来add("string"),但是list1优惠让他可以add(123)。(Object嘛)所以不可以    }    //show1和show2不能相互替代,且不能构成重载    public void show1(List<String> l){    }    public void show2(List<Object> l){    }

通配符

    /*    2. 通配符的使用    通配符:?    类A是类B的父类,G<A>和G<B>是没有关系的。二者共同的父类时:G<?>     */    @Test    public void test2(){        List<Object> l1 = null;        List<String> l2 = null;        List<?> l = null;        l = l1;        l = l2;        //编译通过,但是由于我们没有初始化l1,l2 所以运行时会有NullPointerException//        print(l1);//        print(l2);    }    public static void print(List<?> list){        Iterator it = list.iterator();        while(it.hasNext()){            Object obj = it.next();            System.out.println(obj);//            System.out.println(it.next());        }    }    @Test    public void test3(){        List<String> l = new ArrayList<String>();        l.add("aa");        l.add("bb");        List<?> l1 = null;        l1 = l;        //添加(写入):对于List<?>就不能向其内部添加数据        //除了添加null之外//        l1.add("11");        //获取(读取):        Object obj = l1.get(0);        System.out.println(obj);    }
   /*    3. 有限制条件的通配符的使用    ? extends A:        G<? extends A> 可以作为G<A>和G<B>的父类的,即?是A的子类或A本身    ? super A:         G<? super A> 可以作为G<A>和G<B>的父类的,即?是A的父类或A本身     */    @Test    public void test4(){        //extends <=        //super >=        List<? extends Person> l1 = null;        List<? super Person> l2 = null;        List<Student> l3 = new ArrayList<Student>();        List<Person> l4 = new ArrayList<Person>();        List<Object> l5 = new ArrayList<Object>();        l1 = l3;        l1 = l4;//        l1 = l5;//        l2 = l3;        l2 = l4;        l2 = l5;        //读取数据        l1 = l3;        Person p = l1.get(0);        //编译不通过        l2 = l4;//        Person p = l2.get(0);        //写入数据:        //编译不通过 因为?代表的可能是比Student还小的类或者和其并列的类//        l1.add(new Student());        //ok:?代表的至少是比Person大的类 所以一定可以加入<=Person的类        l2.add(new Person());        l2.add(new Student());    }

File

  • File类的理解
/** * File类的使用 * 1. File类的一个对象,代表一个文件或者一个文件目录(俗称:文件夹) * 2. File类声明在java.io包下 * 3. File类中涉及到关于文件或者文件目录的创建、删除、重命名、修改时间、文件大小等方法 * 并未涉及到写入或者读取文件内容的操作,如果需要读取或写入文件内容,必须使用IO流来完成 * 4. 后续File类的对象常会作为参数传递到流的constructor中,指明读取或者写入的“终点” * @author shc * @create 2021-06-03 12:05 */
  • File类的实例化
    /*    1. 如何创建File类的实例        File(String filePath)        File(String parentPath,String childPath)        File(File parentFile,String child)    2.    相对路径:相较于某个路径下,指明的路径    绝对路径:包含在盘符在内的文件或文件目录的路径3. 路径分隔符windows:\\unix:/     */    @Test    public void test1(){        //构造器1 现在还只是内存层面的对象,并没有在硬盘中造一个文件        File file1 = new File("hello.txt"); //相对路径:相较于当前Module(在当前Module下有一个hello.txt)        File file2 = new File("C:\\Users\\de'l'l\\IdeaProjects\\workspace_idea1\\day08");//绝对路径        System.out.println(file1);        System.out.println(file2);        //构造器2        File file3 = new File("C:\\Users\\de'l'l\\IdeaProjects","workspace_idea1");//文件目录        System.out.println(file3);        //构造器3        File file4 = new File(file3,"hh.txt");        System.out.println(file4);    }
  • IDEA相对路径

    • Junit的单元测试方法里:相较于Module(因为每个Module都要新引入Junit)
    • main方法里:相较于当前工程下
  • Eclipse:无论是单元测试方法还是main(),相对路径都是在当前Module下。

image-20210604211644642

image-20210604211654032

image-20210604211707812

  • -子类和父类的同名方法,要么都是static,要么都不是static
posted on 2021-08-21 10:02  咕噜辰  阅读(38)  评论(0)    收藏  举报