2024Java面试题集合高频20道

1. Java集合框架有哪些常见的接口?

Java集合框架主要接口包括:

  • Collection:根接口,包含操作单一元素集合的方法(如add、remove、clear等)。
  • List:有序集合,允许重复元素。常见实现类有ArrayList、LinkedList、Vector等。
  • Set:无序集合,不允许重复元素。常见实现类有HashSet、LinkedHashSet、TreeSet等。
  • Queue:队列接口,通常用于FIFO顺序的集合。常见实现类有LinkedList、PriorityQueue等。
  • Deque:双端队列接口,允许在两端插入和删除元素。常见实现类有ArrayDeque、LinkedList等。
  • Map:键值对集合,不属于Collection接口。常见实现类有HashMap、TreeMap、LinkedHashMap等。

示例代码:

List<String> arrayList = new ArrayList<>();
Set<String> hashSet = new HashSet<>();
Queue<String> linkedListQueue = new LinkedList<>();
Map<String, String> hashMap = new HashMap<>();

2. ArrayList和LinkedList的区别?

  • ArrayList

    • 基于动态数组实现,底层是一个数组。
    • 随机访问效率高,时间复杂度为O(1)。
    • 插入和删除元素时效率低,尤其是中间位置,时间复杂度为O(n)。
  • LinkedList

    • 基于双向链表实现。
    • 随机访问效率低,时间复杂度为O(n)。
    • 插入和删除元素时效率高,时间复杂度为O(1),特别是首尾位置。

示例代码:

List<Integer> arrayList = new ArrayList<>();
arrayList.add(1);
arrayList.add(2);
arrayList.add(3);
System.out.println("ArrayList: " + arrayList);

List<Integer> linkedList = new LinkedList<>();
linkedList.add(1);
linkedList.add(2);
linkedList.add(3);
System.out.println("LinkedList: " + linkedList);

3. HashSet和TreeSet的区别?

  • HashSet

    • 基于哈希表实现。
    • 插入、删除和查找时间复杂度为O(1)。
    • 不保证元素的顺序。
  • TreeSet

    • 基于红黑树实现。
    • 插入、删除和查找时间复杂度为O(log n)。
    • 保证元素的自然顺序(或根据提供的比较器)。

示例代码:

Set<String> hashSet = new HashSet<>();
hashSet.add("b");
hashSet.add("a");
hashSet.add("c");
System.out.println("HashSet: " + hashSet);

Set<String> treeSet = new TreeSet<>();
treeSet.add("b");
treeSet.add("a");
treeSet.add("c");
System.out.println("TreeSet: " + treeSet);

4. 如何选择合适的集合类型?

  • List:需要有序集合且允许重复元素时,选择ArrayList或LinkedList。ArrayList适合频繁随机访问,LinkedList适合频繁插入和删除。
  • Set:需要无序集合且不允许重复元素时,选择HashSet或TreeSet。HashSet性能更好,TreeSet可以保证有序。
  • Queue:需要先进先出(FIFO)集合时,选择LinkedList或PriorityQueue。PriorityQueue适合需要优先级处理的队列。
  • Map:需要键值对存储时,选择HashMap或TreeMap。HashMap性能更好,TreeMap可以保证键的有序。

5. 如何对List进行排序?

使用Collections.sort()方法或者List自带的sort()方法,可以传入自定义比较器。

示例代码:

List<Integer> list = new ArrayList<>(Arrays.asList(3, 1, 2));
Collections.sort(list); // 自然顺序排序
System.out.println("Sorted List: " + list);

list.sort(Comparator.reverseOrder()); // 逆序排序
System.out.println("Reverse Sorted List: " + list);

6. 如何去除List中的重复元素?

使用HashSet来过滤重复元素,再转换回List。

示例代码:

List<String> list = new ArrayList<>(Arrays.asList("a", "b", "a"));
Set<String> set = new HashSet<>(list);
list = new ArrayList<>(set);
System.out.println("List after removing duplicates: " + list);

7. 如何实现线程安全的集合?

使用Collections.synchronizedList()等方法创建线程安全集合,或者使用并发集合类如CopyOnWriteArrayListConcurrentHashMap

示例代码:

List<String> synchronizedList = Collections.synchronizedList(new ArrayList<>());
Map<String, String> concurrentMap = new ConcurrentHashMap<>();

// 使用同步集合时需在外部同步
synchronized (synchronizedList) {
    synchronizedList.add("a");
}

8. 什么是HashMap的工作原理?

HashMap基于哈希表实现,通过计算键的哈希码确定存储位置,使用链表或红黑树处理哈希冲突。

  • 哈希函数:计算键的哈希码,哈希码经过扰动函数(高位混合)得到哈希值。
  • 桶数组:哈希值对桶数组长度取模得到桶的索引,将键值对存储在相应桶中。
  • 链表/红黑树:处理哈希冲突,链表长度超过阈值(默认8)时转换为红黑树。

9. 什么是fail-fast机制?

在迭代集合时,如果集合结构被修改(如增加或删除元素),会抛出ConcurrentModificationException。这种机制用于快速检测并发修改问题。

示例代码:

List<String> list = new ArrayList<>(Arrays.asList("a", "b", "c"));
for (String s : list) {
    if ("b".equals(s)) {
        list.remove(s); // 会抛出ConcurrentModificationException
    }
}

10. 什么是fail-safe机制?

并发集合类(如CopyOnWriteArrayList)在迭代过程中允许修改,使用副本进行迭代,不会抛出ConcurrentModificationException

示例代码:

CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>(Arrays.asList("a", "b", "c"));
for (String s : list) {
    if ("b".equals(s)) {
        list.remove(s); // 不会抛出异常
    }
}
System.out.println("List after modification: " + list);

11. 如何合并两个List?

使用addAll()方法将一个List中的所有元素添加到另一个List中。

示例代码:

List<String> list1 = new ArrayList<>(Arrays.asList("a", "b"));
List<String> list2 = new ArrayList<>(Arrays.asList("c", "d"));
list1.addAll(list2);
System.out.println("Merged List: " + list1);

12. 如何使用Comparator自定义排序?

创建Comparator接口的实现类,重写compare方法,传入Collections.sort()或List的sort()方法。

示例代码:

List<String> list = new ArrayList<>(Arrays.asList("apple", "banana", "cherry"));
list.sort(new Comparator<String>() {
    @Override
    public int compare(String s1, String s2) {
        return s1.length() - s2.length(); // 按字符串长度排序
    }
});
System.out.println("List sorted by length: " + list);

13. 如何实现深拷贝一个集合?

使用序列化和反序列化实现深拷贝,或者手动遍历集合并复制每个元素。

示例代码(序列化实现深拷贝):

import java.io.*;
import java.util.ArrayList;
import java.util.List;

public class DeepCopy {
    public static <T> List<T> deepCopy(List<T> list) throws IOException, ClassNotFoundException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(baos);
        oos.writeObject(list);

        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bais);
        return (List<T>) ois.readObject();
    }

    public static void main(String[] args) throws IOException, ClassNotFoundException {
        List<String> originalList = new ArrayList<>(Arrays.asList("a", "b", "c"));
        List<String> copiedList = deepCopy(originalList);
        copiedList.add("d");
        System.out.println("Original List: " + originalList);
        System.out.println("Copied List: " + copiedList);
    }
}

14. 什么是Java中的WeakHashMap?

WeakHashMap

是一种特殊的Map,其键是弱引用,如果键没有其他强引用存在,会被垃圾收集器回收。

示例代码:

import java.util.Map;
import java.util.WeakHashMap;

public class WeakHashMapExample {
    public static void main(String[] args) {
        Map<String, String> map = new WeakHashMap<>();
        String key = new String("key");
        map.put(key, "value");

        key = null; // key对象没有强引用,会被GC回收
        System.gc();

        System.out.println("Map after GC: " + map);
    }
}

15. 什么是EnumSet和EnumMap?

  • EnumSet:专为枚举类型设计的高效集合,只能包含枚举类型的值,内部使用位向量实现,非常高效。

  • EnumMap:专为枚举类型键设计的高效Map,只能使用枚举类型作为键,内部使用数组实现,性能优于普通的HashMap。

示例代码:

enum Day { MONDAY, TUESDAY, WEDNESDAY }

public class EnumSetAndEnumMap {
    public static void main(String[] args) {
        EnumSet<Day> enumSet = EnumSet.of(Day.MONDAY, Day.TUESDAY);
        System.out.println("EnumSet: " + enumSet);

        EnumMap<Day, String> enumMap = new EnumMap<>(Day.class);
        enumMap.put(Day.WEDNESDAY, "Midweek");
        System.out.println("EnumMap: " + enumMap);
    }
}

16. 如何转换数组为集合?

使用Arrays.asList()方法将数组转换为List,或者使用Collections.addAll()将数组元素添加到集合中。

示例代码:

String[] array = {"a", "b", "c"};
List<String> list = Arrays.asList(array);
System.out.println("List from array: " + list);

List<String> list2 = new ArrayList<>();
Collections.addAll(list2, array);
System.out.println("List from array using Collections.addAll: " + list2);

17. 如何实现不可变集合?

使用Collections.unmodifiableList()等方法创建不可变集合,或者使用Guava库的ImmutableList等类。

示例代码:

List<String> list = new ArrayList<>(Arrays.asList("a", "b", "c"));
List<String> immutableList = Collections.unmodifiableList(list);
System.out.println("Immutable List: " + immutableList);

// 尝试修改将抛出UnsupportedOperationException
// immutableList.add("d");

List<String> guavaImmutableList = ImmutableList.of("a", "b", "c");
System.out.println("Guava Immutable List: " + guavaImmutableList);

18. 如何使用PriorityQueue?

PriorityQueue是基于优先级堆的队列,元素按优先级排序。

示例代码:

PriorityQueue<Integer> priorityQueue = new PriorityQueue<>();
priorityQueue.add(3);
priorityQueue.add(1);
priorityQueue.add(2);
System.out.println("Priority Queue elements in order:");
while (!priorityQueue.isEmpty()) {
    System.out.println(priorityQueue.poll()); // 输出1, 2, 3
}

19. 什么是BlockingQueue?

BlockingQueue是并发队列,支持线程安全的阻塞插入和移除操作,如ArrayBlockingQueueLinkedBlockingQueue

示例代码:

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

public class BlockingQueueExample {
    public static void main(String[] args) throws InterruptedException {
        BlockingQueue<String> blockingQueue = new LinkedBlockingQueue<>();
        blockingQueue.put("a");
        System.out.println("Element from BlockingQueue: " + blockingQueue.take());
    }
}

20. 如何使用ConcurrentHashMap?

ConcurrentHashMap是线程安全的Map,适用于高并发环境,提供高效的并发操作。

示例代码:

import java.util.concurrent.ConcurrentHashMap;
import java.util.Map;

public class ConcurrentHashMapExample {
    public static void main(String[] args) {
        Map<String, String> concurrentMap = new ConcurrentHashMap<>();
        concurrentMap.put("key1", "value1");
        concurrentMap.put("key2", "value2");

        System.out.println("ConcurrentHashMap: " + concurrentMap);
    }
}
  • 27
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

伟主教

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值