Java学习笔记——集合补充

Java学习笔记——集合补充

Iterable接口中除了Colletion以及Map接口之外,还有一个比较常用的接口 —— Deque

Deque接口
public interface Deque<E> extends Queue<E>

Deque —— 双端队列接口继承了Queue接口,同时Stack类也已被声明为过时,官方同样推荐用Deque替代Stack

实现该接口的类/继承该接口的接口包括LinkedList、ArrayQueue、ConcurrentLinkedQueue、以及BlockingQueue接口

常用方法

节选自Deque - Java 11中文版 - API参考文档 (apiref.com)

booleanoffer(E e)将指定的元素插入此双端队列表示的队列中(换句话说,在此双端队列的尾部),如果它是立即可行且不会违反容量限制,返回 true在成功和 false如果当前没有空间可用。
booleanofferFirst(E e)将指定元素插入此双端队列的前面,除非它违反容量限制。
booleanofferLast(E e)在此双端队列的末尾插入指定的元素,除非它违反容量限制。
Epeek()检索但不移除此双端队列表示的队列的头部(换句话说,此双端队列的第一个元素),如果此双端队列为空,则返回 null
EpeekFirst()检索但不删除此双端队列的第一个元素,如果此双端队列为空,则返回 null
EpeekLast()检索但不删除此双端队列的最后一个元素,如果此双端队列为空,则返回 null
Epoll()检索并删除此双端队列表示的队列的头部(换句话说,此双端队列的第一个元素),如果此双端队列为空,则返回 null
EpollFirst()检索并删除此双端队列的第一个元素,如果此双端队列为空,则返回 null
EpollLast()检索并删除此双端队列的最后一个元素,如果此双端队列为空,则返回 null
Epop()从此双端队列表示的堆栈中弹出一个元素。
voidpush(E e)如果可以在不违反容量限制的情况下立即执行此操作, IllegalStateException到此双端队列表示的堆栈(换句话说,在此双端队列的头部),如果当前没有可用空间则抛出 IllegalStateException

offer、peek、poll一组可以作为队列使用

pop、push可以当作栈使用 其中pop等同于peek()操作

Deque<Integer> deque = new LinkedList<>();
deque.offer(1);
deque.offer(2);
deque.offer(3);
System.out.println(deque.peek());	// 1
System.out.println(deque.pop());	// 1
阻塞队列

阻塞队列—— BlockingQueue接口,也是常见的集合接口。其可以理解为支持两个附加操作的队列。(阻塞的插入与阻塞的移除)

方法抛出异常返回特殊值一直阻塞超时退出
插入add(e)offer(e)put()offer(e ,time,unit)
移除remove()poll()take()poll(time , unit)
检查element()peek()//
//测试
BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(3);
for (int i = 0; i < 3; i++) {
    queue.add(i);
}
// queue.add(4);  Exception in thread "main" java.lang.IllegalStateException: Queue full
System.out.println(queue.offer(4)); //false
System.out.println(queue.offer(4,3,TimeUnit.SECONDS)); //3s后 返回false
queue.put(4); //线程被阻塞
java中常见的阻塞队列的实现类

1)ArrayBlockingQueue

构造器

//需要传入一个容量参数 、 默认为不保证线程公平的阻塞队列
public ArrayBlockingQueue(int capacity) {
    this(capacity, false);
}

//可以指定参数——线程是否公平
public ArrayBlockingQueue(int capacity, boolean fair) {
    if (capacity <= 0)
        throw new IllegalArgumentException();
    this.items = new Object[capacity];
    lock = new ReentrantLock(fair);		//通过可重入锁,来实现访问者的公平性
    notEmpty = lock.newCondition();		//用于唤醒等待取出元素的线程
    notFull =  lock.newCondition();		//用于唤醒等待添加元素的线程
}

2)LinkedBlockingQueue

一般用于创建无界的阻塞队列,锁为非公平锁

// 提供了空参构造器 , 默认长度为int最大值
public LinkedBlockingQueue() {
    this(Integer.MAX_VALUE);
}

3)PriorityBlokingQueue

支持优先级的无界阻塞队列

//默认按照自然排序升序排列
BlockingQueue<Integer> queue = new PriorityBlockingQueue<>();
queue.put(2);
queue.put(1);
System.out.println(queue.take());   // 1

4)SynchronousQueue

不存储元素的阻塞队列——每一个put 必须等待take操作

// 可以指定线程是否公平(默认非公平)
public SynchronousQueue() {
    this(false);
}

应用场景 —— Executors.newCachedThreadPool() Cached线程池中,采用了此种阻塞队列

public static ExecutorService newCachedThreadPool() {
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                  60L, TimeUnit.SECONDS,
                                  new SynchronousQueue<Runnable>());
}

5)DelayQueue

支持延迟获取元素的阻塞队列(元素需实现Delayed接口,在后期关于线程池的文章中再具体解释)

底层通过PriorityBlokingQueue实现(例如,我们可以通过延迟时间进行排序)

6)LinkedTransferQueue

相较于其他阻塞队列,多了transfer方法与tryTransfer方法

前者,如果没有消费者接受,就继续阻塞,后者则立即返回(未接受就返回false)

/**
	输出结果:true false 0
*/
public class LinkedTransferQueueDemo {
    public static void main(String[] args) {
        //创建一个阻塞队列
        LinkedTransferQueue<Integer> queue = new LinkedTransferQueue<>();

        //线程A用于获取元素
        new Thread(() -> {
            try {
                System.out.println(queue.take());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"A").start();

        //线程B添加元素
        new Thread(() -> {
            for (int i = 0; i < 2; i++) {
                System.out.println(queue.tryTransfer(i));
            }
        },"B").start();
        
    }
}

7)LinkedBlockingDeque

与2类似,但为双端队列

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值