Java Map实现类面试题

news/2025/2/25 19:22:29

Java Map实现类面试题

HashMap

Q1: HashMap的实现原理是什么?

HashMap基于哈希表实现,使用数组+链表+红黑树(Java 8)的数据结构。

java">public class HashMapPrincipleExample {
    // 模拟HashMap的基本结构
    public class SimpleHashMap<K, V> {
        private static final int DEFAULT_CAPACITY = 16;
        private static final float LOAD_FACTOR = 0.75f;
        
        private Entry<K, V>[] table;
        private int size;
        
        private static class Entry<K, V> {
            K key;
            V value;
            Entry<K, V> next;
            
            Entry(K key, V value, Entry<K, V> next) {
                this.key = key;
                this.value = value;
                this.next = next;
            }
        }
        
        @SuppressWarnings("unchecked")
        public SimpleHashMap() {
            table = new Entry[DEFAULT_CAPACITY];
        }
        
        public V put(K key, V value) {
            int hash = hash(key);
            int index = indexFor(hash, table.length);
            
            // 遍历链表
            for (Entry<K, V> e = table[index]; e != null; e = e.next) {
                if (e.key.equals(key)) {
                    V oldValue = e.value;
                    e.value = value;
                    return oldValue;
                }
            }
            
            // 添加新节点
            addEntry(hash, key, value, index);
            return null;
        }
        
        private void addEntry(int hash, K key, V value, int index) {
            Entry<K, V> e = table[index];
            table[index] = new Entry<>(key, value, e);
            if (++size > table.length * LOAD_FACTOR) {
                resize(2 * table.length);
            }
        }
        
        private int hash(K key) {
            return key == null ? 0 : key.hashCode();
        }
        
        private int indexFor(int hash, int length) {
            return hash & (length - 1);
        }
    }
}

Q2: HashMap的扩容机制是怎样的?

java">public class HashMapResizeExample {
    public void demonstrateResize() {
        HashMap<String, Integer> map = new HashMap<>();
        
        // 1. 默认初始容量16,负载因子0.75
        System.out.println("初始容量:" + 16);
        System.out.println("扩容阈值:" + (16 * 0.75));
        
        // 2. 指定初始容量
        HashMap<String, Integer> customMap = new HashMap<>(32);
        
        // 3. 模拟扩容过程
        for (int i = 0; i < 13; i++) {
            map.put("key" + i, i);
            System.out.println("当前大小:" + map.size());
        }
    }
    
    // 扩容时的数据迁移
    public void demonstrateRehash() {
        HashMap<String, Integer> map = new HashMap<>(4);
        map.put("A", 1); // index = hash("A") & (4-1)
        map.put("B", 2);
        map.put("C", 3);
        // 扩容后 index = hash("A") & (8-1)
    }
}

TreeMap

Q3: TreeMap的实现原理是什么?

TreeMap基于红黑树实现,可以保证键的有序性。

java">public class TreeMapPrincipleExample {
    // 1. 自然排序
    public void naturalOrdering() {
        TreeMap<String, Integer> map = new TreeMap<>();
        map.put("C", 3);
        map.put("A", 1);
        map.put("B", 2);
        // 按键的自然顺序排序
        for (Map.Entry<String, Integer> entry : map.entrySet()) {
            System.out.println(entry.getKey() + ": " + entry.getValue());
        }
    }
    
    // 2. 自定义排序
    public void customOrdering() {
        TreeMap<Person, String> map = new TreeMap<>((p1, p2) -> {
            int ageCompare = Integer.compare(p1.getAge(), p2.getAge());
            if (ageCompare != 0) return ageCompare;
            return p1.getName().compareTo(p2.getName());
        });
        
        map.put(new Person("Tom", 20), "Student");
        map.put(new Person("Jerry", 18), "Student");
        map.put(new Person("Bob", 20), "Teacher");
    }
    
    // 3. 范围操作
    public void rangeOperations() {
        TreeMap<Integer, String> map = new TreeMap<>();
        for (int i = 1; i <= 10; i++) {
            map.put(i, "Value" + i);
        }
        
        // 获取子Map
        Map<Integer, String> subMap = map.subMap(3, 7);
        // 获取小于等于key的Entry
        Map.Entry<Integer, String> floorEntry = map.floorEntry(5);
        // 获取大于等于key的Entry
        Map.Entry<Integer, String> ceilingEntry = map.ceilingEntry(5);
    }
}

LinkedHashMap

Q4: LinkedHashMap的特点是什么?

LinkedHashMap在HashMap的基础上维护了一个双向链表,可以保持插入顺序或访问顺序。

java">public class LinkedHashMapExample {
    // 1. 插入顺序
    public void insertionOrder() {
        LinkedHashMap<String, Integer> map = new LinkedHashMap<>();
        map.put("A", 1);
        map.put("B", 2);
        map.put("C", 3);
        // 遍历时保持插入顺序
    }
    
    // 2. 访问顺序
    public void accessOrder() {
        LinkedHashMap<String, Integer> map = 
            new LinkedHashMap<>(16, 0.75f, true);  // accessOrder = true
        map.put("A", 1);
        map.put("B", 2);
        map.put("C", 3);
        
        map.get("A");  // 访问A,A会移到链表末尾
        // 遍历时A会在最后
    }
    
    // 3. LRU缓存实现
    public class LRUCache<K, V> extends LinkedHashMap<K, V> {
        private final int capacity;
        
        public LRUCache(int capacity) {
            super(capacity, 0.75f, true);
            this.capacity = capacity;
        }
        
        @Override
        protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
            return size() > capacity;
        }
    }
}

ConcurrentHashMap

Q5: ConcurrentHashMap的实现原理是什么?

ConcurrentHashMap在Java 8中使用CAS和synchronized来保证并发安全。

java">public class ConcurrentHashMapExample {
    // 1. 基本使用
    public void basicUsage() {
        ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
        map.put("A", 1);
        map.putIfAbsent("B", 2);
        map.computeIfAbsent("C", key -> 3);
    }
    
    // 2. 原子操作
    public void atomicOperations() {
        ConcurrentHashMap<String, AtomicInteger> map = new ConcurrentHashMap<>();
        map.putIfAbsent("counter", new AtomicInteger(0));
        
        // 线程安全的计数器
        map.get("counter").incrementAndGet();
    }
    
    // 3. 并发迭代
    public void concurrentIteration() {
        ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
        // 填充数据
        for (int i = 0; i < 100; i++) {
            map.put("key" + i, i);
        }
        
        // 并发遍历
        map.forEach(8, (key, value) -> 
            System.out.println(key + ": " + value));
    }
}

Q6: 如何选择合适的Map实现类?

java">public class MapSelectionExample {
    public void demonstrateUsage() {
        // 1. 一般用途,非线程安全
        Map<String, Object> hashMap = new HashMap<>();
        
        // 2. 需要有序
        Map<String, Object> treeMap = new TreeMap<>();
        
        // 3. 需要记住插入顺序
        Map<String, Object> linkedHashMap = new LinkedHashMap<>();
        
        // 4. 需要线程安全
        Map<String, Object> concurrentMap = new ConcurrentHashMap<>();
        
        // 5. 需要同步
        Map<String, Object> synchronizedMap = 
            Collections.synchronizedMap(new HashMap<>());
        
        // 6. 实现LRU缓存
        Map<String, Object> lruCache = 
            new LinkedHashMap<>(16, 0.75f, true) {
                @Override
                protected boolean removeEldestEntry(Map.Entry eldest) {
                    return size() > 100; // 限制大小为100
                }
            };
    }
    
    // 使用场景示例
    public void usageScenarios() {
        // 1. 频繁插入删除
        HashMap<String, Object> hashMap = new HashMap<>();
        
        // 2. 需要排序
        TreeMap<String, Object> treeMap = new TreeMap<>();
        
        // 3. 需要保持插入顺序
        LinkedHashMap<String, Object> linkedHashMap = new LinkedHashMap<>();
        
        // 4. 高并发场景
        ConcurrentHashMap<String, Object> concurrentMap = 
            new ConcurrentHashMap<>();
    }
}

面试关键点

  1. 理解HashMap的底层实现
  2. 掌握HashMap的扩容机制
  3. 了解TreeMap的排序原理
  4. 熟悉LinkedHashMap的特点
  5. 理解ConcurrentHashMap的并发机制
  6. 掌握Map的选择原则
  7. 注意线程安全问题
  8. 理解性能和内存消耗

http://www.niftyadmin.cn/n/5865878.html

相关文章

分布式深度学习:探索无限可能

分布式深度学习:探索无限可能 大家好,我是Echo_Wish,一名专注于人工智能和Python的自媒体创作者。今天,我们将深入探讨分布式深度学习,这个技术不仅是AI发展的前沿,更是应对大规模数据和复杂模型的关键解决方案。随着数据量和模型复杂度的不断增加,传统的单机深度学习已…

netty十八罗汉之——挖耳罗汉(Decoder)

佛教中除不听各种淫邪声音之外&#xff0c;更不可听别人的秘密。因他论耳根最到家&#xff0c;故取挖耳之形&#xff0c;以示耳根清净。 来看看netty的核心组件解码器Decoder Decoder的作用半包&#xff0c;粘包问题从模板和装饰器模式看Decoder解码原理 1.Decoder作用 最根本…

解决鼠标唤醒关屏状态下的笔记本

以下是通过计划任务和PowerShell实现鼠标唤醒控制的全网独家解决方案,基于Windows事件触发机制,结合设备管理API实现精准控制,最终实现仅需通过win+l锁定屏幕,再关闭屏幕,既不会出现唤醒笔记问的问题: 一、技术原理深度解析 1. 事件触发机制 Windows安全子系统在锁屏/…

C语言基本知识------指针(4)

1. 回调函数是什么&#xff1f; 回调函数就是⼀个通过函数指针调用的函数。 如果你把函数的指针&#xff08;地址&#xff09;作为参数传递给另⼀个函数&#xff0c;当这个指针被⽤来调⽤其所指向的函数 时&#xff0c;被调⽤的函数就是回调函数。 void qsort(void base,//指针…

JavaWeb-在idea中配置Servlet项目

文章目录 在idea中进行Servlet项目的配置(较新的idea版本)创建一个空的JavaSE项目(Project)创建一个普通的JavaSE板块(module)添加Web项目的配置定义一个对象模拟实现接口在web.xml中配置路径映射配置项目到Tomcat服务器启动Tomcat服务器进行测试 在idea中进行Servlet项目的配置…

Python入门教程丨3.7 数据可视化

我们之前提到了一款可视化神器ECharts&#xff0c;但那是基于JS的来开发和使用的&#xff0c;现在我们有了pyecharts库&#xff0c;就可以在python中方便的调用&#xff01; 1. Pyecharts 库 1.1 什么是 Pyecharts&#xff1f; Pyecharts是 ECharts 的 Python 接口&#xff0…

2025 银行业科技金融创新与发展报告

在数字化浪潮席卷全球的今天,银行业正站在科技金融创新的前沿。2025 年,科技与金融的深度融合将重塑银行业的生态格局,推动金融服务迈向智能化、高效化和普惠化的新阶段。 一、科技金融创新的背景与意义 (一)全球经济数字化转型加速 随着信息技术的飞速发展,全球经济正…

火绒终端安全管理系统V2.0网络防御功能介绍

火绒终端安全管理系统V2.0 【火绒企业版V2.0】网络防御功能包含网络入侵拦截、横向渗透防护、对外攻击检测、僵尸网络防护、Web服务保护、暴破攻击防护、远程登录防护、恶意网址拦截。火绒企业版V2.0的网络防御功能&#xff0c;多层次、多方位&#xff0c;守护用户终端安全。 …