java 数据集合(set、map、list)

1、list
    1.1分类
        list分为ArrayList和LinkedList,这两者都实现了List接口,但是这两个只有这本质的区别,ArrayList底层使用的是数组,
        而LinkedList 底层 使用的是链表。显然,由于这个区别,两者的使用场景和效率都有很大的不同。
    1.2 ArrayList
        先看一下它的类图,继承自AbstractList,实现了6个接口,这里要说一下Collection和Iterable。Collection接口是java中集合类
        型数据的必要接口,Iterable接口允许我们使用foreach的方法来遍历集合。
            
         下面是我在看api和源码过程中总结的几点
        (1)ArrayList的默认初始容量为10
        (2)ArrayList通过ensure Capacity(int x)函数来确保本身容量够大。每一次向ArrayList里面添加数据的时候,会
         调用ensureCapacity(int x)看是否需要加大容量,如果要,那么就计算原长度的1.5倍然后加1,假设这个值为y,比较
         参数x和y的大小,使用大的值作为ArrayList新的容量。而这里容量的改变是通过数组的新建和拷贝来完成的。在底层新建一
         个数组,然后将ArrayList原来的数据拷贝过去,这样就完成了容量的增加。在即将添加大量数据的时候,可以通
         过ensureCapacity这个函数设置一个大一点的容量,一次来减少之后添加大量数据时的拷贝等操作。
        (3)关于同步。ArrayList不是线程安全的,如果在多线程中使用ArrayList作为共享变量,必须要在调用的时候做好同步操作,
         或者在创建的时候使用 Collections.synchronizedList方法( List list = Collections.synchronizedList(new ArrayList(...)); )。
        (4)快速失败机制:此类的 iterator 和 listIterator 方法返回的迭代器是快速失败的,在创建迭代器之后,除非通过迭代器自
        身的 remove 或 add 方法从结构上对列表进行修改,否则在任何时间以任何方式对列表进行修改,迭代器都会抛出     
        ConcurrentModificationException。因此,面对并发的修改,迭代器很快就会完全失败,而不是冒着在将来某个不确定时间
        发生任意不确定行为的风险。
    1.3 LinkedList
        和ArrayList的功能不同,ArrayList更多的作为类似于可变长数组来进行使用,而LinkedList一般作为队列或者栈来使用。看下面
        的实现类图,它实现了Deque(双端队列接口)和Queue(队列接口)
        
        总结:
        (1)和ArrayList一样,它也是非线程安全的,而且也有快速失败机制。
        (2)可以作为队列和栈来使用,而且一般也是这么使用,因为底层是链表,所以遍历起来效率肯定不如ArrayList。
2、map
    2.1 HashMap
        map的子类其实有很多,但是我只用过HashMap,所以就先只看HashMap吧。HashMap里有一个加载因子的概念,当
        HashMap的当前数据条数大于最大条数和加载因子的积时,HashMap就会进行数据重构,然后使HashMap拥有原来两倍
        大小。HashMap的默认初始大小为16.
    2.2 哈希函数
        map的数据结构是一种<key,value>键值对,其底层本质上也是数组,HashMap在存放value的时候,利用key的hashcode
        计算出哈希值,然后用哈希值计算出value在数组中的位置,然后将value存进去。哈希函数就是一个保证不同的hashcode可以换
        成不同的哈希值的函数。
   
3、set
    3.1 介绍
        set是一个不能存放相同元素的容器,存放在set里的元素是无序的,而且每一个都是唯一的。
    3.2 HashSet
        HashSet是一种封装了HashMap的set,它利用HashMap实现了无序和唯一。HashSet把自己的元素存放在HashMap的key中,
        利用key的唯一性实现set中数据不可重复。
    3.3 遍历
        HashSet不能按照下标查找,只能利用迭代器iterator进行遍历。
    3.4 TreeSet
        一个可以进行排序的Set,我们可以通过向TreeSet传递Comparator接口来自定义排序规则。直接看下面使用的例子:
TreeSet treeSet = new TreeSet(new Comparator() {
            public int compare(Object o1, Object o2) {
                Dog a = (Dog) o1;
                Dog b = (Dog) o2;
                return  a.age>b.age?-1:(a.age == b.age?0:1) ;
            }
        });
        Dog a = new Dog();
        a.setAge(1);
        a.setName("a");
        Dog b = new Dog();
        b.setAge(2);
        b.setName("b");
        Dog c = new Dog();
        c.setAge(3);
        c.setName("c");
        treeSet.add(a);
        treeSet.add(b);
        treeSet.add(c);
        Iterator iterator = treeSet.iterator();
        while (iterator.hasNext()){
            Dog dog = (Dog) iterator.next();
            System.out.println(dog.name);
        }
        首先定义了一个带有比较功能的TreeSet,每一次执行add()插入数据的时候就会进行比较,然后排序。函数  
        compare(Object  o1, Object o2)  会对o1和o2参数的age属性进行比较,o1代表的 是当前插入的数据,o2可以先不管。如果当前
        插入的数据大,返回-1;小,返回1;相等,返回0。
        执行上面代码的结果:
c
b
a
        需要注意的是,如果我们让函数在相等的时候返回0,那么后加入的数据就会覆盖前面的数据。为了避免数据的丢失,我们可以在
        相等的时候也返回1或-1,这样就能利用TreeSet实现排序的集合了。
    3.5 TreeSet 原理
        TreeSet 底层是一颗红黑树,实现原理有兴趣的话可以自行百度,其使用方法可以向上面那样。















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值