集合框架

 

  Java的集合类主要由两个根接口CollectionMap派生而出。集合框架中所有具体类都实现了CloneableSerializable接口。

Set:存储一组不重复的元素,继承了Collection主要有2个实现方式:

        1.TreeSet(依赖于TreeMap,实际上通过TreeMap实现):

                子类LinkedHashSe使用链表扩展实现HashSet类,支持对元素排序,打印时顺序与添加时的顺序一致。

        2.HashSet(依赖于HashMap,实际上通过HashMap实现): 

                打印时有序,默认字符串比较的顺序,也可以排序.

                HashSet中是允许存入null值的,但是在HashSet中仅仅能够存入一个null值。

List,继承了Collection

        实现类:LinkedList, ArrayList, Vector, Stack(Stack继承自Vector,比较古老)

        ArrayList是一个动态数组,每一个ArrayList都有一个初始容量(10).擅长于随机访问。同时ArrayList是非同步的。

        LinkedList是一个双向链表,不能随机访问,LinkedList也是非同步的。

        Vector:与ArrayList相似,但是Vector是同步的。所以说Vector是线程安全的动态数组。它的操作与ArrayList几乎一样。

Map(与collection没什么关系):默认情况下只能对键排序

 

 

        HashMap:无序

        LinkedHashMap:和插入顺序一致

        treeMap:按键排序

    三种遍历map的方法

 

  Map<String,Integer>  treeMap = new TreeMap<>();
  treeMap.put("abc", 1);
  treeMap.put("ABC", 2);
  treeMap.put("xyz", 3);
  treeMap.put("XYZ", 4);
  System.out.println("treeMap:" +treeMap);
  
  System.out.println("第一种遍历方式:通过Map.keySet遍历key,通过key取出对应的value值");
  for (String key : treeMap.keySet()) {
   System.out.println(key + "--" + treeMap.get(key));
  }
  // 一键一值 => entry
  System.out.println("第二种遍历方式:通过Map.entrySet使用迭代器遍历key和value");
  Set<Map.Entry<String,Integer>>  entrySet = treeMap.entrySet();
  Iterator<Entry<String, Integer>> entrySetIt =  entrySet.iterator();
  while(entrySetIt.hasNext()){
   Map.Entry<String, Integer> entry = entrySetIt.next();
   System.out.println(entry.getKey() + "--" + entry.getValue());
  }
  
  System.out.println("第三种遍历方式:直接遍历Map.entrySet集合---容量大时使用");
  for(Entry<String,Integer> entry : treeMap.entrySet()){
   System.out.println(entry.getKey() + "--" + entry.getValue());
  }

 

队列

      队列是数据结构中比较重要的一种类型,它支持 FIFO,尾部添加、头部删除(先进队列的元素先出队列),跟我们生活中的排队类似。

队列有两种:

  • 单队列
  • 循环队列

单队列就是常见的队列, 每次添加元素时,都是添加到队尾:

以数组实现的队列为例,初始时队列长度固定为 4,font 和 rear 均为 0:

 

 

每添加一个元素,rear 后移一位。当添加四个元素后, rear 到了索引为 4 的位置:

 

这时 a1,a2 出队,front 后移动到 2:

 

这时想要再添加两个元素,但 rear 后移两位后就会越界:

 

明明有三个空位,却只能再放入一个!这就是单队列的“假溢出”情况。

 

 

(上述参考借鉴自 http://www.nowamagic.net/librarys/veda/detail/2350

针对这种情况,解决办法就是后面满了,就再从头开始,也就是头尾相接的循环。这就是 “循环队列” 的概念。

循环队列:

循环队列中,
rear = (rear - size) % size

接着上面的例子,当 rear 大于 队列长度时,rear = ( 5 - 5) % 5 = 0 :

这样继续添加时,还可以添加几个元素:

 

那如何判断队列是否装满元素了呢,单使用 front == rear 无法判断究竟是空的还是满了。

两种方法:

  1. 加个标志 flag ,初始为 false,添加满了置为 true;
  2. 不以 front = rear 为放满标志,改为 (rear - front) % size = 1。

法 2 的公式放满元素时空余了一个位置,这个公式是什么意思呢?

 

 

当 rear < font 时,队列中元素分为两部分: size - font 和 rear ,也就是 rear + size - font。以上述图片为例,队列中元素个数 = 1 + 5 - 2 = 4.

 

 

Queue(存储用先进先出方式处理的对象):

 

 

         Blocking Queue

         Abstract Queue

         Deque(双端队列,支持从两端操作队列元素

                  --LinkedList 

                --ArrayDeque

                       

          ArrayDeque-一个基于数组实现的双端队列,默认底层数组长度为16,当元素超过集合容量时,系统会在底层重新分配一个Object数组来存储数据。

Deque 的实现类主要分为两种场景

  • 一般场景
    • LinkedList 大小可变的链表双端队列,允许元素为 null
    • ArrayDeque 大下可变的数组双端队列,不允许 null并发场景
    • LinkedBlockingDeque 如果队列为空时,获取操作将会阻塞,知道有元素添加

  并发场景

  • LinkedBlockingDeque 如果队列为空时,获取操作将会阻塞,知道有元素添加

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值