`

面试总结----java集合

    博客分类:
  • java
 
阅读更多
春节刚过,打算换一份工作,于是就开始了一段准备面试的生活,准备的这段时间内,学到很

多知识,现在做个总结,总共分java集合、java虚拟机、多线程、spring等四个部分,由于个

人知识有限,在总结过程中,难免出现不当地方,如发现,请指出。
下面就开始第一部分:java集合

一、集合结构图
图中蓝色字体标示的是接口,黑色字体标示的是具体实现
1.Collection结构图



2.Map结构图



说明:
  a.List表示列表,里面的元素可重复,有顺序
   
  • Vector为List的线程安全实现,底层采用数组的作为存储结构,方法上使用synchronized来实现同步,并发性差,因为这里采用的是对象的内部锁,一个对象只有一个内部锁,当一个线程获取了这个对象(这里的对象即为Vector类型的对象)的内部锁之后,其他线程想要获取这个对象的内部锁的时候,只能等待了,关于线程安全问题,在线程部分讲解。与Vector相对应的非线程安全实现为ArrayList.

  •    
  • ArrayList底层采用数组作为存储结构来实现List的,当执行add操作的时候,如果数组已经装满数据了,这时就需要数组容量扩展为原来的1.5倍。
  •    
  • LinkedList底层使用双向链表作为存储结构,传入的泛型参数一定要是基本类型除外的其他类型,链表中的每个节点使用Node来存储,Node的定义如下:
  • 
        private static class Node<E> {
            E item;
            Node<E> next;
            Node<E> prev;
    
            Node(Node<E> prev, E element, Node<E> next) {
                this.item = element;
                this.next = next;
                this.prev = prev;
            }
        }
    

    每次进行add操作的时候默认是插在链表的末尾,也可以指定插入位置。
      b.Set表示集合,即里面的元素不能重复,重复与否是通过泛型类型的实际类型的比较器来实现的,底层是通过Map来实现的,利用Map的key不能重复的特性来实现。
      
  • HashSet底层使用HashMap来实现,HashSet里面的所有元素,对应到HashMap里面就是一个Key,向HashSet里面添加元素的代码如下:
  •     public boolean add(E e) {
            return map.put(e, PRESENT)==null;
        }
    

    PRESENT为Object对象。
      
  • TreeSet是通过TreeMap来存储数据和排序的。
  •   c.Queue为队列,即满足FIFO规则,对应有单向队列(从一边进,从另一边出),双向队列(两边都可以进出,从一边进,可以从两边出)。ArrayBlockingQueue、LinkedBlockingQueue主要用来实现生产者消费者模式的应用。
      
  • ArrayBlockingQueue,数组实现的单向队列,底层通过数组来实现。ArrayBlockingQueue里面的属性有:
  •     /** The queued items */
        final Object[] items;
    
        /** items index for next take, poll, peek or remove */
        int takeIndex;
    
        /** items index for next put, offer, or add */
        int putIndex;
    
        /** Number of elements in the queue */
        int count;
    
        /*
         * Concurrency control uses the classic two-condition algorithm
         * found in any textbook.
         */
    
        /** Main lock guarding all access */
        final ReentrantLock lock;
        /** Condition for waiting takes */
        private final Condition notEmpty;
        /** Condition for waiting puts */
        private final Condition notFull;
    


    Object数组用来存储数据,takeIndex用来存放下一个可以取得数据的索引位置,每次进行取出数据时,需要进行如下操作:
     takeIndex = inc(takeIndex);
    
        final int inc(int i) {
            return (++i == items.length) ? 0 : i;
        }
    

    putIndex用来存放下一个可以存放元素的索引位置,存储操作时,putIndex的设置为:
     putIndex = inc(putIndex);
        final int inc(int i) {
            return (++i == items.length) ? 0 : i;
        }
    

    lock和condition主要用来保证线程安全。

     
  • LinkedBlockingQueue使用双向链表来实现,底层数据结构为:
  •     static class Node<E> {
            E item;
    
            /**
             * One of:
             * - the real successor Node
             * - this Node, meaning the successor is head.next
             * - null, meaning there is no successor (this is the last node)
             */
            Node<E> next;
    
            Node(E x) { item = x; }
        }
    
        /**
         * Head of linked list.
         * Invariant: head.item == null
         */
        private transient Node<E> head;
    
        /**
         * Tail of linked list.
         * Invariant: last.next == null
         */
        private transient Node<E> last;
    

    每次元素进入队列时都是接在last的后面,出队列时,都是从head那里出。
    使用java.util.concurrent包下面的ReentrantLock、Condition、AtomicInteger来保证线程安全。

      d.Deque即为double ended queue,双端队列,两边都可以进出队列。
       
  • ArrayDeque底层使用数组来实现,部分代码为:
  •     private transient E[] elements;
    
        /**
         * The index of the element at the head of the deque (which is the
         * element that would be removed by remove() or pop()); or an
         * arbitrary number equal to tail if the deque is empty.
         */
        private transient int head;
    
        /**
         * The index at which the next element would be added to the tail
         * of the deque (via addLast(E), add(E), or push(E)).
         */
        private transient int tail;
    

    非线程安全的双端队列实现。
     
  • LinkedBlockingDeque底层采用双向链表来实现,部分代码为:
  •     /** Doubly-linked list node class */
        static final class Node<E> {
            /**
             * The item, or null if this node has been removed.
             */
            E item;
    
            /**
             * One of:
             * - the real predecessor Node
             * - this Node, meaning the predecessor is tail
             * - null, meaning there is no predecessor
             */
            Node<E> prev;
    
            /**
             * One of:
             * - the real successor Node
             * - this Node, meaning the successor is head
             * - null, meaning there is no successor
             */
            Node<E> next;
    
            Node(E x) {
                item = x;
            }
        }
    
        /**
         * Pointer to first node.
         * Invariant: (first == null && last == null) ||
         *            (first.prev == null && first.item != null)
         */
        transient Node<E> first;
    
        /**
         * Pointer to last node.
         * Invariant: (first == null && last == null) ||
         *            (last.next == null && last.item != null)
         */
        transient Node<E> last;
    

    使用ReentrantLock、Condition来保证线程安全。
    e.Map的实现常用的有三种,HashMap、Hashtable、TreeMap.Map没有继承Collection,原因为:Collection一次只存储单个元素,Map一次存储需要存储Key和Value。
     
  • HashMap底层是一个数组,数组里面的类型是Entry,Entry的定义如下:
  •     static class Entry<K,V> implements Map.Entry<K,V> {
            final K key;
            V value;
            Entry<K,V> next;
            int hash;
    
            /**
             * Creates new entry.
             */
            Entry(int h, K k, V v, Entry<K,V> n) {
                value = v;
                next = n;
                key = k;
                hash = h;
            }
    
            public final boolean equals(Object o) {
                if (!(o instanceof Map.Entry))
                    return false;
                Map.Entry e = (Map.Entry)o;
                Object k1 = getKey();
                Object k2 = e.getKey();
                if (k1 == k2 || (k1 != null && k1.equals(k2))) {
                    Object v1 = getValue();
                    Object v2 = e.getValue();
                    if (v1 == v2 || (v1 != null && v1.equals(v2)))
                        return true;
                }
                return false;
            }
    
            public final int hashCode() {
                return Objects.hashCode(getKey()) ^ Objects.hashCode(getValue());
            }
         //省略部分代码
        }
    

       可以看出,每个Entry里面有key、hash、value、next为Entry的属性。数组中的每个位置都是一个Entry类型的数据,这个数据含有指向下一个Entry的属性,即next.在进行put操作的时候,如果当前数组里面存储的元素数量超出了事先设置的阈值,则需要进行容量扩展,需要进行数组元素值复制、rehash等操作。底层的数组及链表的数据结构为:



    HashMap中的Key需要重写hashCode和equals,hashCode用来定位,equals用来比较,及hashCode的作用为将需要插入的元素的位置定位到数组的哪个索引上,equals用来和链表上的元素进行比较,看是要插入的值的key是否已经存在,如果存在,则将新value替换老value值。

     
  • Hashtable为HashMap的线程安全实现,但是有如下不同:
  •      HashMap的key和value都可以为null,Hashtable的key和value不能为null,否则抛出异常,原因是Hashtable继承了Dictionary,Dictionary中的key和value不允许为null。
         hash算法不一样。HashMap的hash算法实现如下:
        
        final int hash(Object k) {
            int h = hashSeed;
            if (0 != h && k instanceof String) {
                return sun.misc.Hashing.stringHash32((String) k);
            }
    
            h ^= k.hashCode();
    
            // This function ensures that hashCodes that differ only by
            // constant multiples at each bit position have a bounded
            // number of collisions (approximately 8 at default load factor).
            h ^= (h >>> 20) ^ (h >>> 12);
            return h ^ (h >>> 7) ^ (h >>> 4);
        }
    

    Hashtable的hash算法实现如下:
    
        private int hash(Object k) {
            // hashSeed will be zero if alternative hashing is disabled.
            return hashSeed ^ k.hashCode();
        }
    

        Hashtable在多数方法上加上了synchronized,即多线程下不会产生并发问题,HashMap会在多线程下产生并发问题。
       
  • TreeMap是红黑树理论的一种实现,维护一个Comparator和一个Entry,Comparator为构造实例时传进来的比较器,红黑树中的每一个节点对应一个Entry,Entry的实现如下:
  • 
        static final class Entry<K,V> implements Map.Entry<K,V> {
            K key;
            V value;
            Entry<K,V> left = null;
            Entry<K,V> right = null;
            Entry<K,V> parent;
            boolean color = BLACK;
       //省略部分代码
    }
    

         可以看出一个Entry有指向父节点,左右子节点的引用。TreeMap的Key需要实现一个比较器,比较好的做法是,构造TreeMap时传入一个比较器,比较器是基于key实现的。


    • 大小: 32.1 KB
    • 大小: 5.8 KB
    • 大小: 14.5 KB
    分享到:
    评论

    相关推荐

      Java面试题资料合集-44套.rar

      java面试-Java集合框架常见面试题 java面试-Java虚拟机(JVM)面试题 51道 java面试-Kafka知识汇总 18道 java面试-Nginx面试题 23道 java面试-RabbitMQ面试题 22道 java面试-Redis面试题(含答案) java面试-...

      Java面试突击-V3.0_Java面试文档_java面试_面试_

      3. **集合框架**:Java集合框架是存储和操作对象的关键工具,包括List、Set、Map接口及其实现类,如ArrayList、LinkedList、HashSet、HashMap等,理解它们的特点和适用场景至关重要。 4. **多线程与并发**:Java...

      2024年java面试题-java集合相关面试题

      根据给定文件的信息,我们可以总结出以下关于Java集合的相关知识点: ### 一、集合容器概述 #### 1.... 集合(Collection)是指在Java中用来存储、...希望这些知识点能帮助你在面试中更好地应对关于Java集合的问题。

      大数据面试复习总结

      大数据面试复习---Java基础---集合类、多线程、JVM 大数据面试复习----常问问题分析 大数据面试复习----画重点----思维导图 大数据面试复习----简历编写 大数据面试复习----练习的面试题+笔试题 大数据面试复习----...

      Java面试题--java8

      Java 8 是一个重要的Java版本,它引入了许多新特性,特别是在函数式编程方面。函数式编程的概念意味着在Java中,函数可以被视...在面试中,对这些Java 8特性的理解和掌握,能显示出开发者对最新技术的敏锐度和专业性。

      最新各大公司企业真实面试题-Java面试题

      最后,"Core Javaceshiti.doc"很可能包含了关于Java核心概念的总结,可能涵盖Java SE的主要部分,例如字符串处理、日期时间API、泛型、枚举、Lambda表达式等。 总的来说,这个压缩包为Java开发者提供了一个全面的...

      19个非常全的Java面试题和面经PDF,辛苦整理,希望帮助到大家

      Java集合.pdf 面试---3. Java并发.pdf 面试---4. JVM&amp;Linux.pdf 面试---5. JavaWeb&HTTP&安全&Git&前端.pdf 面试---6. MySQL.pdf 面试---7. 分布式理论---问题.pdf 面试---8. 分布式理论---组件.pdf 面试---9. ...

      java集合-面试总结 .pos

      java集合总结

      02-Java集合容器面试题(2020最新版)-重点.pdf

      ### Java集合容器知识点详解 #### 一、集合容器概述 - **定义**:集合容器是Java平台提供的标准组件,主要用于存储对象。集合框架提供了一套统一的接口和实现,使得开发者能够灵活地处理不同类型的数据集合。 ####...

      02-Java集合容器面试题-重点.docx

      Java集合容器概述、集合框架、List、Set、Map接口、Iterator、ArrayList、LinkedList、Vector、HashSet、HashMap、Queue、BlockingQueue、ConcurrentHashMap等。 Java 集合容器概述 Java 集合容器是用于存储数据...

      软件大数据面试笔试复习资料面试技巧HR面试常问的问题总结面试笔试题整理资料合集.zip

      01大数据面试复习----Java基础---集合类、多线程、JVM 02大数据面试复习----画重点----常问问题分析 03大数据面试复习----画重点----精心制作热门技术思维导图 04大数据面试复习----画重点----56家+真实互联网大公司...

      java面试必问面试宝典--千方百计

      这份“java面试必问面试宝典--千方百计”很可能是总结了众多面试者的经验,包含了Java核心技术、面试技巧以及应对策略。以下是一些可能涵盖的知识点: 1. **Java基础知识**: - Java语法:类、对象、封装、继承、...

      java面试宝典-高手总结

      【Java面试宝典-高手总结】是一篇针对Java初学者和面试准备者的指南,涵盖了JavaEE和WEB开发的基础知识。以下是对这些知识点的详细解析: 1. Java是强类型语言,这意味着在Java中,变量必须在使用前进行声明并初始...

      算法、数据结构和编程面试示例 - Java - 下载.zip

      总结来说,“算法、数据结构和编程面试示例 - Java - 下载.zip”是一个全面的Java面试准备资源,通过深入学习和实践,你将能够提升自己的技术水平,应对各种面试挑战,从而在竞争激烈的IT职场中脱颖而出。...

      2019年蚂蚁课堂-余胜军主编Java工程师面试宝典-V1.0.pdf

      这本书是每特教育培训在对历年面试经验进行深入分析和总结的基础上编纂而成,被誉为高薪就业的必备宝典。 首先,书中涵盖了Java基础,包括但不限于Java语法特性,如类、对象、封装、继承、多态等面向对象编程的基本...

      100IT名企java面试必考面试题.PDF

      1. **基础知识**:这包括Java语法、数据类型、流程控制(如if、switch、for、while)、数组和集合(List、Set、Map)、异常处理等。面试官可能会询问你关于这些基本概念的理解以及如何在实际编程中应用它们。 2. **...

      计算机后端-Java-Java高并发从入门到面试教程-课程总结.zip

      在本课程中,我们深入探讨了Java高并发编程这一核心领域,这不仅是Java开发者必备的技能,也是在面试中常被考察的知识点。这个“计算机后端-Java-Java高并发从入门到面试教程”旨在帮助初学者和有经验的开发者们掌握...

      Java集合面试问题

      根据给定文件的信息,我们可以提炼出以下关于Java集合的关键知识点: ### 1. Java集合概述与常见类 ...以上是对Java集合框架的基础介绍及关键知识点的总结,希望对你理解Java集合的概念有所帮助。

      java集合类面试题总结

      Java 集合类面试题总结 Java 集合类是 Java 语言中的一种重要组件,用于存储和操作数据。下面总结了 Java 集合类的一些常见问题和答案。 HashMap 和 Hashtable 的区别 HashMap 和 Hashtable 都是 Java 中的散列表...

      2020最新Java企业面试题汇总-1000多份.txt

      根据给定文件的信息,我们可以总结出以下相关的Java知识点和面试准备要点: ### 一、Java基础知识 #### 1. Java语言特点 - **面向对象**:封装、继承、多态。 - **平台无关性**:通过JVM实现跨平台运行。 - **自动...

    Global site tag (gtag.js) - Google Analytics