Java学习笔记7

一.泛型

1. 泛型:广泛的数据类型,确保类型安全的一种途径

2.instanceof也是确保类型安全的一种手段

(1).泛型类的定义

在类或方法上都可以使用泛型

返回的类型和传入的类型是同一种

    EasyGenericity<J,M,N,Y,Easy> {
    private M m;
    public void test(M m,N n){
    }
    public static <J extends List> J testA(J j){
        return j;
    }
    public <E> E test(E e){
        return e;
    }

类型转换时没有明确对象的数据类型进行强制数据类型转换会抛出ClassCaseException(类型转换异常)类型不安全

    public static void main(String[] args) {
        testA(new ArrayList());
        //类型安全
        List list=new ArrayList();
        list.add("123");
        for(Object object:list){
            //类型不安全
            String str=(String)object;
            System.out.println(str);
        }
        List<String> listA=new ArrayList<>();
        listA.add("123");

        Map<String,Object> map=new HashMap<>();
        //只要是泛型就是对象
    }
}

泛型类的语法格式:

第一种:class 泛型类名称<类型形参列表> {
               // 这里可以使用类型参数
                }
第二种:  class 泛型类名称<类型形参列表> extends 继承类/* 这里可以使用类型参数 */ {
                // 这里可以使用类型参数
                }

在返回值类型前面定义

注:泛型只能接受类,所有的基本数据类型必须使用包装类!

T可以代表任何数据类型,方便我们指定类型传参。

注:类名后的 <T> 代表占位符,表示当前类是一个泛型类

当我们不确定数据类型时,我们可以暂时使用一个字母 T代替数据类型,例如写一个方法,但是我们不知道它是传递的是什么数据类型,我们就可以使用泛型,到时候只要指明T是什么数据类型,就可以使用了。

(2).泛型的数组使用

泛型使用数组时: T[] ts = new T[5];//是不对的

原因:在编译时时,会把T转换为Object,而Object范围很大,到时候就无法确定是什么数据类型了。

(3).泛型的上界

语法格式:

           class 泛型类名称<类型形参 extends 类型边界> {
...
}

示例:

        public class MyArray<E extends Number> {
        ...                                //相当于 < T >
        }

解析:可以把<E extends Number>当成<T>来看,Number可能是接口,也可能是类。而此时的T,有了限制,T的范围是 Number的子类

:泛型无下界。

(4).泛型的方法

语法格式:方法限定符 <类型形参列表> 返回值类型 方法名称(形参列表) { ... }

       //静态的泛型方法 需要在static后用 <> 声明泛型类型参数
                public static <E> void swap(E[] array, int i, int j) {
                        E t = array[i];
                        array[i] = array[j];
                         array[j] = t;
                 }

:其他的方法不需要用 <> 声明

二、Set集合

(1).   

                 List是有序集合(取出顺序与添加顺序是一样的),Set是无序的(取出顺序和添加顺序不一样)

                Set中不能存储相同的数据。

(2).1. 实例化HashSet

 HashSet set=new HashSet();

                HashSet可以存储空值

                TreeSet不能存储空值

存入数据使用add();

set.add("123");

删除数据

set.remove("123");

获取Set元素个数

 set.size();

TreeSet底层使用红黑树实现   不能存Null值

树的遍历:先序遍历   中序遍历   后序遍历   (根据访问根节点的顺序命名),无论哪种便利都是先左后右

2. TreeSet遍历方式  中序遍历

TreeSet  内部使用二叉树   内部节点是可以比较大小
同一个TreeSet对象中存储的内容都应该是可比较的
默认情况下不能存储不同类型

3. LinkedHashSet 是有序的集合Set,是线程不安全的,底层实现是LinkedHashMap

三.Map

1. Map 存的是键值对 键---名字 值---对象 Map不属于collection

2. 

        Map map = new HashMap();
        //存放数据
        map.put("A1", "张三");
        //可以通过存入数据的key获取存入的对象
        Object obj = map.get("A1");//获取A1对应的value值
        System.out.println(obj);
        ///通过key删除键值对
        Object rem_obj = map.remove("A1");
        System.out.println("删除的value值:" + rem_obj);
        //是否包含key
        map.containsKey("A1");
        //是否包含value值
        map.containsValue("张三");
        //获取所有的key
        Set setKey = map.keySet();
        //获取所有的value
        Collection con = map.values();

        map.put(null, null);//可以为空
        map.put("A1", null);
        map.put("A1", "张三");
        System.out.println(map);

3. TreeMap

        key应该是可比较的,不能是null

4. 

Hashtable key和value都不能是null值

Hashtable 是线程安全的集合,效率较低

5.

ConcurrentHashMap 线程安全 效率较高

四.HashMap 底层实现---数组加链表
HashMap的数组默认容量为16
每次扩容两倍
扩容阈值   0.75   存入12个元素扩容
一个链上达到8就对该链进行树化
一个树上的元素低于6这个数就退化成链
最小树化容量阈值   64
如果数组的长度没有达到64,优先扩容

注意:线程安全的Map 有两个  Hashtable(性能不高)和ConcurrentHashMap(性能优异  锁的颗粒度比较小)
  • 10
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值