赶紧收藏!2024 年最常见 100道 Java 基础面试题(十五)

上一篇地址:赶紧收藏!2024 年最常见 100道 Java 基础面试题(十四)-CSDN博客

二十九、在Queuepoll()remove()有什么区别?

Queue是Java中一个接口,代表了一个队列,它是一种特殊的集合,遵循先进先出(FIFO)的原则。poll()remove()Queue接口的两个方法,它们用于从队列中移除元素,但它们的行为略有不同:

  1. poll()方法

    • poll()方法从队列头部移除并返回元素。如果队列是空的,poll()方法将返回null。它不会抛出异常。
  2. remove()方法

    • remove()方法也用于从队列头部移除元素,但是,如果队列为空,remove()方法将抛出一个NoSuchElementException。在行为上,它更像是集合的remove()方法。
  3. 空队列时的行为

    • 当队列为空时,poll()remove()的主要区别在于对空队列的处理方式。poll()在队列为空时返回null,而remove()会抛出异常。
  4. 使用场景

    • 如果你不确定队列是否为空,并且希望在队列为空时安全地处理,那么poll()是一个更好的选择,因为它不会抛出异常。
    • 如果你确信队列不为空,或者在队列为空时宁愿让程序抛出异常,那么可以使用remove()方法。
  5. ArrayListLinkedList的关系

    • 在Java中,ArrayListLinkedList都实现了Queue接口。LinkedList作为队列使用时,其poll()remove()方法的行为与上面描述的一致。而ArrayList作为队列使用时,通常推荐只使用remove()方法来保持与Queue接口的一致性,因为ArrayList的随机访问特性使得poll()方法的实现可能不够高效。

示例代码

import java.util.LinkedList;
import java.util.Queue;

public class QueueExample {
    public static void main(String[] args) {
        Queue<Integer> queue = new LinkedList<>();
        queue.add(1);
        queue.add(2);
        
        // 使用poll()方法
        Integer polledValue = queue.poll(); // 返回1,队列中的第一个元素
        System.out.println("Polled value: " + polledValue);
        
        // 使用remove()方法
        // Integer removedValue = queue.remove(); // 返回2,队列中的第一个元素
        // System.out.println("Removed value: " + removedValue);
        
        // 如果队列为空,remove()将抛出NoSuchElementException
        // 如果队列为空,poll()将返回null
        Integer emptyPoll = queue.poll(); // 返回null,队列为空
        System.out.println("Empty poll: " + emptyPoll);
    }
}

总结

  • Queuepoll()方法在队列为空时返回null,而remove()方法在队列为空时抛出异常。
  • 在处理队列时,选择使用poll()remove()应基于对空队列的预期处理方式。

三十、哪些集合类是线程安全的?

在Java中,线程安全的集合类可以安全地在多线程环境中使用,而不需要额外的同步措施。以下是一些线程安全的集合类:

  1. Collections.synchronizedList(List<T> list)

    • 返回一个线程安全的List包装器,所有List的列表操作都被同步。
  2. Collections.synchronizedSet(Set<T> s)

    • 返回一个线程安全的Set包装器,所有Set的集合操作都被同步。
  3. Collections.synchronizedMap(Map<K,V> m)

    • 返回一个线程安全的Map包装器,所有Map的映射操作都被同步。
  4. Vector<T>

    • VectorArrayList的线程安全版本,所有方法都是同步的。
  5. Stack<T>

    • StackVector的子类,也是线程安全的,用于实现栈的功能。
  6. Hashtable<K,V>

    • Hashtable是线程安全的Map实现,所有方法都是同步的。
  7. ConcurrentHashMap<K,V>

    • 从Java 1.5开始,ConcurrentHashMap提供了更好的并发性能,它使用分段锁来允许并发的读写操作。
  8. CopyOnWriteArrayList<T>

    • 这是一个线程安全的变体,适用于读操作远多于写操作的场景。
  9. CopyOnWriteArraySet<T>

    • 这是一个线程安全的Set,使用CopyOnWriteArrayList作为其底层数据结构。
  10. ArrayBlockingQueue<T>

    • 这是一个由Array支持的有界阻塞队列,适用于需要阻塞操作的场景。
  11. LinkedBlockingQueue<T>

    • 这是一个可选容量的阻塞队列,基于链表实现。
  12. PriorityBlockingQueue<T>

    • 这是一个无界优先级队列,元素按照自然顺序排序或根据提供的Comparator排序。

示例代码

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Vector;

public class ThreadSafeCollections {
    public static void main(String[] args) {
        // 使用Collections工具类创建线程安全的List
        List<String> syncList = Collections.synchronizedList(new ArrayList<>());

        // Vector是线程安全的
        Vector<String> vector = new Vector<>();

        // Hashtable是线程安全的Map
        Hashtable<String, String> hashtable = new Hashtable<>();

        // ConcurrentHashMap是线程安全的Map,提供更好的并发性能
        ConcurrentHashMap<String, String> concurrentHashMap = new ConcurrentHashMap<>();
    }
}

总结

  • 线程安全的集合类可以避免在多线程环境中由于并发修改导致的问题。
  • Java提供了多种线程安全的集合类,包括同步包装器和专门的线程安全集合类。
  • 在选择线程安全的集合类时,应考虑并发性能和特定场景的需求。例如,ConcurrentHashMap通常比Hashtable提供更好的性能,因为它允许更多的并发操作。
  • 19
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值