Java中的集合


Java集合指标准库中对于一些不同类型集合的封装

集合中的接口

大体上分为Collection和Map两种;
Collection又包括List、Set、Queue三种;

List、Set、Queue

List是一个有序集合、元素会在容器中的特定位置进行存储、可以使用迭代器或者使用下标进行一个随机访问: List可以精确控制每个元素在列表中的插入位置。 用户可以通过它们的整数索引(在列表中的位置)访问元素,并在列表中搜索元素。而且List可以存储多个Null;
对于List,java中还有一个ListIterator,相对于传统迭代器,它可以实现逆序访问和添加元素;

 public static void main(String[] args) {
        List<Integer> list = new ArrayList<>(Arrays.asList(1,2,5,6,2,6));
        list.forEach(System.out::print);//125626
        
        
        ListIterator<Integer> iterator = list.listIterator();
        while (iterator.hasNext()){
            //iterator.previous();反向遍历
            //iterator.remove();删除指针处元素;
            iterator.add(1);//用于在每个元素遍历时插入新元素到前后;给每个元素前加上一个 1;
            iterator.next();
            iterator.set(0);//用于在指针处的设值,把每个元素置为 0 ;
        }
        System.out.println(list.toString());//[1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0]
        
    }

Set,相对于List它不会存储重复的元素,因此写入的对象,需要重写hashcode与equals;而且存入的数据没有按照顺序,即无法通过下标来快速访问;
Queue,队列的快速实现,主要用于按照一定顺序存取元素;而且需要避免存入null值;

队列通常但不一定以 FIFO(先进先出)方式对元素进行排序。 如优先级队列,它根据提供的比较器或元素的自然顺序对元素进行排序,以及对元素进行 LIFO(后进先出)排序的 LIFO 队列(或堆栈)。 在 FIFO 队列中,所有新元素都插入到队列的尾部。 其他类型的队列可能使用不同的放置规则。 每个Queue实现都必须指定其排序属性。 offer方法用于插入一个元素,否则返回false 。

Queue<Integer> queue = new PriorityQueue<>();
        //添加元素,错误情况下add返回异常,offer返回false;
        queue.add(1);
        queue.offer(1);
        //删除元素,错误情况下,remove返回异常,poll返回null
        queue.remove();
        queue.poll();
        //返回队首元素,不会移除元素
        Integer peek = queue.peek();
        peek = queue.element();

集合具体实现

ArrayList和LinkedList

ArrayList:基于动态数组,连续内存存储,适合下标访问(随机访问),扩容机制:因为数组长度固定,超出长度存数据时需要新建数组,然后将老数组的数据拷贝到新数组,如果不是尾部插入数据还会涉及到元素的移动(往后复制一份,插入新元素),使用尾插法并指定初始容量可以极大提升性能。
LinkedList:基于链表,可以存储在分散的内存中,适合做数据插入及删除操作,不适合查询:需要逐一遍历;
简而言之两种List基本对应了数组和链表的特点;数组适合随机访问,尾插;
链表适合随机添加删除;

HashSet

使用ArrayList和LinkedList尽管可以快速进行集合中的按序存储,但都是基于下标来实现访问,如果不知道下标,依然要二次遍历;
HashSet基于散列表实现,通过元素的hash值为每个对象进行一个绑定存储;可以add添加元素,并通过contains进行元素是否存在的快速查询;但是不能保证迭代的顺序;

Java中的散列表是通过数组加链表实现,数组的每一个位置上使用链表来处理hash冲突;
1、如果需要访问一个对象,首先计算其hash值,
2、然后使用hash值对于数组长度进行一个取余操作来计算其在数组中的存储位置;
3、如果发生了hash冲突,则以节点方式在链表后面进行数据的查询;

Hashset中因为使用了hashcode,存入的对象建议需要重写hashcode与equals;因为hash冲突时,值是否重复时需要用到equals进行判断;

TreeSet

相对于散列集,他保证了一个迭代的顺序,输入的值会排序后进行输出;

基于红黑树实现,每次将一个新元素插入时,会将其放在正确的排序位置下。
因此添加元素时其效率会低于HashSet,而且在使用TreeSet时的元素需要实现Comparable接口,但是其检索重复数据会相对快一些;

ArrayDeque与LinkedList

实现了Queue,主要用于高速的在队尾插入,并在队首删除元素;实现了一个双向队列;主要的方法有addFirst(),addLast(),removeFirst,removeLast,offerFirst,offerLast,pollFirst,pollLast;等

PriorityQueue

PriorityQueue优先队列中的元素可以以任意顺序插入,但会有序检索;在任何时候使用remove均会取优先队列中最小元素;迭代处理也不需要排序;

优先队列使用堆来实现,堆是一个二叉树,其添加元素和删除的操作会让最小的元素移到根,不需要再全部排序;

优先级队列是无界的,但具有控制用于存储队列中元素的数组大小的内部容量。 它始终至少与队列大小一样大。 当元素被添加到优先级队列时,它的容量会自动增加。

HashMap与TreeMap

主要体现一个键值映射的方式。对于键值key会进行散列处理,因此要求key需要有不可重复;TreeMap是一种顺序排序的访问;

WeakHashMap

通过使用弱引用来保存键值;适用于需要自动回收无用键值对的时候;

LinkedHashMap和LinkedHashSet

记录了插入元素项的顺序,避免了散列表将顺序改变;
基本实现原理是插入元素时并入了一个双向链表;通过给存入的节点加上一个前指针实现;

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值