精华内容
下载资源
问答
  • java集合详解和集合面试题目

    万次阅读 多人点赞 2018-02-12 11:01:14
    一、集合与数组 数组(可以存储基本数据类型)是用来存现对象的一种容器,但是数组的长度固定,不适合在对象数量未知的情况下使用。 集合(只能存储对象,对象类型可以不一样)的长度可变,可在多数情况下使用。 ...

     

    一、集合与数组

    数组(可以存储基本数据类型)是用来存现对象的一种容器,但是数组的长度固定,不适合在对象数量未知的情况下使用。

    集合(只能存储对象,对象类型可以不一样)的长度可变,可在多数情况下使用。

    二、层次关系

    如图所示:图中,实线边框的是实现类,折线边框的是抽象类,而点线边框的是接口

    Collection接口是集合类的根接口,Java中没有提供这个接口的直接的实现类。但是却让其被继承产生了两个接口,就是Set和List。Set中不能包含重复的元素。List是一个有序的集合,可以包含重复的元素,提供了按索引访问的方式。

    Map是Java.util包中的另一个接口,它和Collection接口没有关系,是相互独立的,但是都属于集合类的一部分。Map包含了key-value对。Map不能包含重复的key,但是可以包含相同的value。

    Iterator,所有的集合类,都实现了Iterator接口,这是一个用于遍历集合中元素的接口,主要包含以下三种方法:
    1.hasNext()是否还有下一个元素。
    2.next()返回下一个元素。
    3.remove()删除当前元素。

    三、几种重要的接口和类简介

    1、List(有序、可重复)
    List里存放的对象是有序的,同时也是可以重复的,List关注的是索引,拥有一系列和索引相关的方法,查询速度快。因为往list集合里插入或删除数据时,会伴随着后面数据的移动,所有插入删除数据速度慢。

    2、Set(无序、不能重复)
    Set里存放的对象是无序,不能重复的,集合中的对象不按特定的方式排序,只是简单地把对象加入集合中。

    3、Map(键值对、键唯一、值不唯一)
    Map集合中存储的是键值对,键不能重复,值可以重复。根据键得到值,对map集合遍历时先得到键的set集合,对set集合进行遍历,得到相应的值。

    对比如下:

     

     

    是否有序

    是否允许元素重复

    Collection

     

     

    List

    Set

    AbstractSet

     

    HashSet

     

    TreeSet

    是(用二叉排序树)

    Map

    AbstractMap

    使用key-value来映射和存储数据,key必须唯一,value可以重复

     

    HashMap

     

    TreeMap

    是(用二叉排序树)

     

    四、遍历

     在类集中提供了以下四种的常见输出方式:

    1)Iterator:迭代输出,是使用最多的输出方式。

    2)ListIterator:是Iterator的子接口,专门用于输出List中的内容。

    3)foreach输出:JDK1.5之后提供的新功能,可以输出数组或集合。

    4)for循环

    代码示例如下:

     for的形式:for(int i=0;i<arr.size();i++){...}

     foreach的形式: for(int i:arr){...}

     iterator的形式:
    Iterator it = arr.iterator();
    while(it.hasNext()){ object o =it.next(); ...}

    五、ArrayList和LinkedList

    ArrayList和LinkedList在用法上没有区别,但是在功能上还是有区别的。LinkedList经常用在增删操作较多而查询操作很少的情况下,ArrayList则相反。

    六、Map集合

    实现类:HashMap、Hashtable、LinkedHashMap和TreeMap

    HashMap 

    HashMap是最常用的Map,它根据键的HashCode值存储数据,根据键可以直接获取它的值,具有很快的访问速度,遍历时,取得数据的顺序是完全随机的。因为键对象不可以重复,所以HashMap最多只允许一条记录的键为Null,允许多条记录的值为Null,是非同步的

    Hashtable

    Hashtable与HashMap类似,是HashMap的线程安全版,它支持线程的同步,即任一时刻只有一个线程能写Hashtable,因此也导致了Hashtale在写入时会比较慢,它继承自Dictionary类,不同的是它不允许记录的键或者值为null,同时效率较低。

    ConcurrentHashMap

    线程安全,并且锁分离。ConcurrentHashMap内部使用段(Segment)来表示这些不同的部分,每个段其实就是一个小的hash table,它们有自己的锁。只要多个修改操作发生在不同的段上,它们就可以并发进行。

    LinkedHashMap

    LinkedHashMap保存了记录的插入顺序,在用Iteraor遍历LinkedHashMap时,先得到的记录肯定是先插入的,在遍历的时候会比HashMap慢,有HashMap的全部特性。

    TreeMap

    TreeMap实现SortMap接口,能够把它保存的记录根据键排序,默认是按键值的升序排序(自然顺序),也可以指定排序的比较器,当用Iterator遍历TreeMap时,得到的记录是排过序的。不允许key值为空,非同步的;

    map的遍历

    第一种:KeySet()
    将Map中所有的键存入到set集合中。因为set具备迭代器。所有可以迭代方式取出所有的键,再根据get方法。获取每一个键对应的值。 keySet():迭代后只能通过get()取key 。
    取到的结果会乱序,是因为取得数据行主键的时候,使用了HashMap.keySet()方法,而这个方法返回的Set结果,里面的数据是乱序排放的。
    典型用法如下:
    Map map = new HashMap();
    map.put("key1","lisi1");
    map.put("key2","lisi2");
    map.put("key3","lisi3");
    map.put("key4","lisi4");  
    //先获取map集合的所有键的set集合,keyset()
    Iterator it = map.keySet().iterator();
     //获取迭代器
    while(it.hasNext()){
    Object key = it.next();
    System.out.println(map.get(key));
    }

    第二种:entrySet()
    Set<Map.Entry<K,V>> entrySet() //返回此映射中包含的映射关系的 Set 视图。(一个关系就是一个键-值对),就是把(key-value)作为一个整体一对一对地存放到Set集合当中的。Map.Entry表示映射关系。entrySet():迭代后可以e.getKey(),e.getValue()两种方法来取key和value。返回的是Entry接口。
    典型用法如下:
    Map map = new HashMap();
    map.put("key1","lisi1");
    map.put("key2","lisi2");
    map.put("key3","lisi3");
    map.put("key4","lisi4");
    //将map集合中的映射关系取出,存入到set集合
    Iterator it = map.entrySet().iterator();
    while(it.hasNext()){
    Entry e =(Entry) it.next();
    System.out.println("键"+e.getKey () + "的值为" + e.getValue());
    }
    推荐使用第二种方式,即entrySet()方法,效率较高。
    对于keySet其实是遍历了2次,一次是转为iterator,一次就是从HashMap中取出key所对于的value。而entryset只是遍历了第一次,它把key和value都放到了entry中,所以快了。两种遍历的遍历时间相差还是很明显的。

    七、主要实现类区别小结

    Vector和ArrayList
    1,vector是线程同步的,所以它也是线程安全的,而arraylist是线程异步的,是不安全的。如果不考虑到线程的安全因素,一般用arraylist效率比较高。
    2,如果集合中的元素的数目大于目前集合数组的长度时,vector增长率为目前数组长度的100%,而arraylist增长率为目前数组长度的50%。如果在集合中使用数据量比较大的数据,用vector有一定的优势。
    3,如果查找一个指定位置的数据,vector和arraylist使用的时间是相同的,如果频繁的访问数据,这个时候使用vector和arraylist都可以。而如果移动一个指定位置会导致后面的元素都发生移动,这个时候就应该考虑到使用linklist,因为它移动一个指定位置的数据时其它元素不移动。
    ArrayList 和Vector是采用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,都允许直接序号索引元素,但是插入数据要涉及到数组元素移动等内存操作,所以索引数据快,插入数据慢,Vector由于使用了synchronized方法(线程安全)所以性能上比ArrayList要差,LinkedList使用双向链表实现存储,按序号索引数据需要进行向前或向后遍历,但是插入数据时只需要记录本项的前后项即可,所以插入数度较快。

    arraylist和linkedlist
    1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。
    2.对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。
    3.对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。 这一点要看实际情况的。若只对单条数据插入或删除,ArrayList的速度反而优于LinkedList。但若是批量随机的插入删除数据,LinkedList的速度大大优于ArrayList. 因为ArrayList每插入一条数据,要移动插入点及之后的所有数据。

    HashMap与TreeMap
    1、 HashMap通过hashcode对其内容进行快速查找,而TreeMap中所有的元素都保持着某种固定的顺序,如果你需要得到一个有序的结果你就应该使用TreeMap(HashMap中元素的排列顺序是不固定的)。
    2、在Map 中插入、删除和定位元素,HashMap是最好的选择。但如果您要按自然顺序或自定义顺序遍历键,那么TreeMap会更好。使用HashMap要求添加的键类明确定义了hashCode()和 equals()的实现。
    两个map中的元素一样,但顺序不一样,导致hashCode()不一样。
    同样做测试:
    在HashMap中,同样的值的map,顺序不同,equals时,false;
    而在treeMap中,同样的值的map,顺序不同,equals时,true,说明,treeMap在equals()时是整理了顺序了的。

    HashTable与HashMap
    1、同步性:Hashtable是线程安全的,也就是说是同步的,而HashMap是线程序不安全的,不是同步的。
    2、HashMap允许存在一个为null的key,多个为null的value 。

    3、hashtable的key和value都不允许为null。

     

    Java集合框架为Java编程语言的基础,也是Java面试中很重要的一个知识点。这里,我列出了一些关于Java集合的重要问题和答案。

    1.Java集合框架是什么?说出一些集合框架的优点?

        每种编程语言中都有集合,最初的Java版本包含几种集合类:Vector、Stack、HashTable和Array。随着集合的广泛使用,Java1.2提出了囊括所有集合接口、实现和算法的集合框架。在保证线程安全的情况下使用泛型和并发集合类,Java已经经历了很久。它还包括在Java并发包中,阻塞接口以及它们的实现。集合框架的部分优点如下:

    (1)使用核心集合类降低开发成本,而非实现我们自己的集合类。

    (2)随着使用经过严格测试的集合框架类,代码质量会得到提高。

    (3)通过使用JDK附带的集合类,可以降低代码维护成本。

    (4)复用性和可操作性。

    2.集合框架中的泛型有什么优点?

        Java1.5引入了泛型,所有的集合接口和实现都大量地使用它。泛型允许我们为集合提供一个可以容纳的对象类型,因此,如果你添加其它类型的任何元素,它会在编译时报错。这避免了在运行时出现ClassCastException,因为你将会在编译时得到报错信息。泛型也使得代码整洁,我们不需要使用显式转换和instanceOf操作符。它也给运行时带来好处,因为不会产生类型检查的字节码指令。

    3.Java集合框架的基础接口有哪些?

        Collection为集合层级的根接口。一个集合代表一组对象,这些对象即为它的元素。Java平台不提供这个接口任何直接的实现。

        Set是一个不能包含重复元素的集合。这个接口对数学集合抽象进行建模,被用来代表集合,就如一副牌。

        List是一个有序集合,可以包含重复元素。你可以通过它的索引来访问任何元素。List更像长度动态变换的数组。

        Map是一个将key映射到value的对象.一个Map不能包含重复的key:每个key最多只能映射一个value。

        一些其它的接口有Queue、Dequeue、SortedSet、SortedMap和ListIterator。

    4.为何Collection不从Cloneable和Serializable接口继承?

        Collection接口指定一组对象,对象即为它的元素。如何维护这些元素由Collection的具体实现决定。例如,一些如List的Collection实现允许重复的元素,而其它的如Set就不允许。很多Collection实现有一个公有的clone方法。然而,把它放到集合的所有实现中也是没有意义的。这是因为Collection是一个抽象表现。重要的是实现。

        当与具体实现打交道的时候,克隆或序列化的语义和含义才发挥作用。所以,具体实现应该决定如何对它进行克隆或序列化,或它是否可以被克隆或序列化。

        在所有的实现中授权克隆和序列化,最终导致更少的灵活性和更多的限制。特定的实现应该决定它是否可以被克隆和序列化。

    5.为何Map接口不继承Collection接口?

        尽管Map接口和它的实现也是集合框架的一部分,但Map不是集合,集合也不是Map。因此,Map继承Collection毫无意义,反之亦然。

        如果Map继承Collection接口,那么元素去哪儿?Map包含key-value对,它提供抽取key或value列表集合的方法,但是它不适合“一组对象”规范。

    6.Iterator是什么?

        Iterator接口提供遍历任何Collection的接口。我们可以从一个Collection中使用迭代器方法来获取迭代器实例。迭代器取代了Java集合框架中的Enumeration。迭代器允许调用者在迭代过程中移除元素。

    7.Enumeration和Iterator接口的区别?

        Enumeration的速度是Iterator的两倍,也使用更少的内存。Enumeration是非常基础的,也满足了基础的需要。但是,与Enumeration相比,Iterator更加安全,因为当一个集合正在被遍历的时候,它会阻止其它线程去修改集合。

    迭代器取代了Java集合框架中的Enumeration。迭代器允许调用者从集合中移除元素,而Enumeration不能做到。为了使它的功能更加清晰,迭代器方法名已经经过改善。

    8.为何没有像Iterator.add()这样的方法,向集合中添加元素?

        语义不明,已知的是,Iterator的协议不能确保迭代的次序。然而要注意,ListIterator没有提供一个add操作,它要确保迭代的顺序。

    9.为何迭代器没有一个方法可以直接获取下一个元素,而不需要移动游标?

        它可以在当前Iterator的顶层实现,但是它用得很少,如果将它加到接口中,每个继承都要去实现它,这没有意义。

    10.Iterater和ListIterator之间有什么区别?

    (1)我们可以使用Iterator来遍历Set和List集合,而ListIterator只能遍历List。

    (2)Iterator只可以向前遍历,而LIstIterator可以双向遍历。

    (3)ListIterator从Iterator接口继承,然后添加了一些额外的功能,比如添加一个元素、替换一个元素、获取前面或后面元素的索引位置。

    11.遍历一个List有哪些不同的方式?

     

    List<String> strList = new ArrayList<>();
    //使用for-each循环
    for(String obj : strList){
      System.out.println(obj);
    }
    //using iterator
    Iterator<String> it = strList.iterator();
    while(it.hasNext()){
      String obj = it.next();
      System.out.println(obj);
    }

        使用迭代器更加线程安全,因为它可以确保,在当前遍历的集合元素被更改的时候,它会抛出ConcurrentModificationException。

    12.通过迭代器fail-fast属性,你明白了什么?

        每次我们尝试获取下一个元素的时候,Iterator fail-fast属性检查当前集合结构里的任何改动。如果发现任何改动,它抛出ConcurrentModificationException。Collection中所有Iterator的实现都是按fail-fast来设计的(ConcurrentHashMap和CopyOnWriteArrayList这类并发集合类除外)。

    13.fail-fast与fail-safe有什么区别?

        Iterator的fail-fast属性与当前的集合共同起作用,因此它不会受到集合中任何改动的影响。Java.util包中的所有集合类都被设计为fail-fast的,而java.util.concurrent中的集合类都为fail-safe的。Fail-fast迭代器抛出ConcurrentModificationException,而fail-safe迭代器从不抛出ConcurrentModificationException。

    14.在迭代一个集合的时候,如何避免ConcurrentModificationException?

        在遍历一个集合的时候,我们可以使用并发集合类来避免ConcurrentModificationException,比如使用CopyOnWriteArrayList,而不是ArrayList。

    15.为何Iterator接口没有具体的实现?

        Iterator接口定义了遍历集合的方法,但它的实现则是集合实现类的责任。每个能够返回用于遍历的Iterator的集合类都有它自己的Iterator实现内部类。

    这就允许集合类去选择迭代器是fail-fast还是fail-safe的。比如,ArrayList迭代器是fail-fast的,而CopyOnWriteArrayList迭代器是fail-safe的。

    16.UnsupportedOperationException是什么?

        UnsupportedOperationException是用于表明操作不支持的异常。在JDK类中已被大量运用,在集合框架java.util.Collections.UnmodifiableCollection将会在所有add和remove操作中抛出这个异常。

    17.在Java中,HashMap是如何工作的?

        HashMap在Map.Entry静态内部类实现中存储key-value对。HashMap使用哈希算法,在put和get方法中,它使用hashCode()和equals()方法。当我们通过传递key-value对调用put方法的时候,HashMap使用Key hashCode()和哈希算法来找出存储key-value对的索引。Entry存储在LinkedList中,所以如果存在entry,它使用equals()方法来检查传递的key是否已经存在,如果存在,它会覆盖value,如果不存在,它会创建一个新的entry然后保存。当我们通过传递key调用get方法时,它再次使用hashCode()来找到数组中的索引,然后使用equals()方法找出正确的Entry,然后返回它的值。下面的图片解释了详细内容。

        其它关于HashMap比较重要的问题是容量、负荷系数和阀值调整。HashMap默认的初始容量是16,负荷系数是0.75。阀值是为负荷系数乘以容量,无论何时我们尝试添加一个entry,如果map的大小比阀值大的时候,HashMap会对map的内容进行重新哈希,且使用更大的容量。容量总是2的幂,所以如果你知道你需要存储大量的key-value对,比如缓存从数据库里面拉取的数据,使用正确的容量和负荷系数对HashMap进行初始化是个不错的做法。

    18.hashCode()和equals()方法有何重要性?

        HashMap使用Key对象的hashCode()和equals()方法去决定key-value对的索引。当我们试着从HashMap中获取值的时候,这些方法也会被用到。如果这些方法没有被正确地实现,在这种情况下,两个不同Key也许会产生相同的hashCode()和equals()输出,HashMap将会认为它们是相同的,然后覆盖它们,而非把它们存储到不同的地方。同样的,所有不允许存储重复数据的集合类都使用hashCode()和equals()去查找重复,所以正确实现它们非常重要。equals()和hashCode()的实现应该遵循以下规则:

    (1)如果o1.equals(o2),那么o1.hashCode() == o2.hashCode()总是为true的。

    (2)如果o1.hashCode() == o2.hashCode(),并不意味着o1.equals(o2)会为true。

    19.我们能否使用任何类作为Map的key?

        我们可以使用任何类作为Map的key,然而在使用它们之前,需要考虑以下几点:

    (1)如果类重写了equals()方法,它也应该重写hashCode()方法。

    (2)类的所有实例需要遵循与equals()和hashCode()相关的规则。请参考之前提到的这些规则。

    (3)如果一个类没有使用equals(),你不应该在hashCode()中使用它。

    (4)用户自定义key类的最佳实践是使之为不可变的,这样,hashCode()值可以被缓存起来,拥有更好的性能。不可变的类也可以确保hashCode()和equals()在未来不会改变,这样就会解决与可变相关的问题了。

        比如,我有一个类MyKey,在HashMap中使用它。

     

    //传递给MyKey的name参数被用于equals()和hashCode()中
    MyKey key = new MyKey('Pankaj'); //assume hashCode=1234
    myHashMap.put(key, 'Value');
    // 以下的代码会改变key的hashCode()和equals()值
    key.setName('Amit'); //assume new hashCode=7890
    //下面会返回null,因为HashMap会尝试查找存储同样索引的key,而key已被改变了,匹配失败,返回null
    myHashMap.get(new MyKey('Pankaj'));

        那就是为何String和Integer被作为HashMap的key大量使用。

    20.Map接口提供了哪些不同的集合视图?

        Map接口提供三个集合视图:

    (1)Set keyset():返回map中包含的所有key的一个Set视图。集合是受map支持的,map的变化会在集合中反映出来,反之亦然。当一个迭代器正在遍历一个集合时,若map被修改了(除迭代器自身的移除操作以外),迭代器的结果会变为未定义。集合支持通过Iterator的Remove、Set.remove、removeAll、retainAll和clear操作进行元素移除,从map中移除对应的映射。它不支持add和addAll操作。

    (2)Collection values():返回一个map中包含的所有value的一个Collection视图。这个collection受map支持的,map的变化会在collection中反映出来,反之亦然。当一个迭代器正在遍历一个collection时,若map被修改了(除迭代器自身的移除操作以外),迭代器的结果会变为未定义。集合支持通过Iterator的Remove、Set.remove、removeAll、retainAll和clear操作进行元素移除,从map中移除对应的映射。它不支持add和addAll操作。

    (3)Set<Map.Entry<K,V>> entrySet():返回一个map钟包含的所有映射的一个集合视图。这个集合受map支持的,map的变化会在collection中反映出来,反之亦然。当一个迭代器正在遍历一个集合时,若map被修改了(除迭代器自身的移除操作,以及对迭代器返回的entry进行setValue外),迭代器的结果会变为未定义。集合支持通过Iterator的Remove、Set.remove、removeAll、retainAll和clear操作进行元素移除,从map中移除对应的映射。它不支持add和addAll操作。

    21.HashMap和HashTable有何不同?

    (1)HashMap允许key和value为null,而HashTable不允许。

    (2)HashTable是同步的,而HashMap不是。所以HashMap适合单线程环境,HashTable适合多线程环境。

    (3)在Java1.4中引入了LinkedHashMap,HashMap的一个子类,假如你想要遍历顺序,你很容易从HashMap转向LinkedHashMap,但是HashTable不是这样的,它的顺序是不可预知的。

    (4)HashMap提供对key的Set进行遍历,因此它是fail-fast的,但HashTable提供对key的Enumeration进行遍历,它不支持fail-fast。

    (5)HashTable被认为是个遗留的类,如果你寻求在迭代的时候修改Map,你应该使用CocurrentHashMap。

    22.如何决定选用HashMap还是TreeMap?

        对于在Map中插入、删除和定位元素这类操作,HashMap是最好的选择。然而,假如你需要对一个有序的key集合进行遍历,TreeMap是更好的选择。基于你的collection的大小,也许向HashMap中添加元素会更快,将map换为TreeMap进行有序key的遍历。

    23.ArrayList和Vector有何异同点?

        ArrayList和Vector在很多时候都很类似。

    (1)两者都是基于索引的,内部由一个数组支持。

    (2)两者维护插入的顺序,我们可以根据插入顺序来获取元素。

    (3)ArrayList和Vector的迭代器实现都是fail-fast的。

    (4)ArrayList和Vector两者允许null值,也可以使用索引值对元素进行随机访问。

        以下是ArrayList和Vector的不同点。

    (1)Vector是同步的,而ArrayList不是。然而,如果你寻求在迭代的时候对列表进行改变,你应该使用CopyOnWriteArrayList。

    (2)ArrayList比Vector快,它因为有同步,不会过载。

    (3)ArrayList更加通用,因为我们可以使用Collections工具类轻易地获取同步列表和只读列表。

    24.Array和ArrayList有何区别?什么时候更适合用Array?

        Array可以容纳基本类型和对象,而ArrayList只能容纳对象。

        Array是指定大小的,而ArrayList大小是固定的。

        Array没有提供ArrayList那么多功能,比如addAll、removeAll和iterator等。尽管ArrayList明显是更好的选择,但也有些时候Array比较好用。

    (1)如果列表的大小已经指定,大部分情况下是存储和遍历它们。

    (2)对于遍历基本数据类型,尽管Collections使用自动装箱来减轻编码任务,在指定大小的基本类型的列表上工作也会变得很慢。

    (3)如果你要使用多维数组,使用[][]比List<List<>>更容易。

    25.ArrayList和LinkedList有何区别?

        ArrayList和LinkedList两者都实现了List接口,但是它们之间有些不同。

    (1)ArrayList是由Array所支持的基于一个索引的数据结构,所以它提供对元素的随机访问,复杂度为O(1),但LinkedList存储一系列的节点数据,每个节点都与前一个和下一个节点相连接。所以,尽管有使用索引获取元素的方法,内部实现是从起始点开始遍历,遍历到索引的节点然后返回元素,时间复杂度为O(n),比ArrayList要慢。

    (2)与ArrayList相比,在LinkedList中插入、添加和删除一个元素会更快,因为在一个元素被插入到中间的时候,不会涉及改变数组的大小,或更新索引。

    (3)LinkedList比ArrayList消耗更多的内存,因为LinkedList中的每个节点存储了前后节点的引用。

    26.哪些集合类提供对元素的随机访问?

        ArrayList、HashMap、TreeMap和HashTable类提供对元素的随机访问。

    27.EnumSet是什么?

        java.util.EnumSet是使用枚举类型的集合实现。当集合创建时,枚举集合中的所有元素必须来自单个指定的枚举类型,可以是显示的或隐示的。EnumSet是不同步的,不允许值为null的元素。它也提供了一些有用的方法,比如copyOf(Collection c)、of(E first,E…rest)和complementOf(EnumSet s)。

    28.哪些集合类是线程安全的?

        Vector、HashTable、Properties和Stack是同步类,所以它们是线程安全的,可以在多线程环境下使用。Java1.5并发API包括一些集合类,允许迭代时修改,因为它们都工作在集合的克隆上,所以它们在多线程环境中是安全的。

    29.并发集合类是什么?

        Java1.5并发包(java.util.concurrent)包含线程安全集合类,允许在迭代时修改集合。迭代器被设计为fail-fast的,会抛出ConcurrentModificationException。一部分类为:CopyOnWriteArrayList、 ConcurrentHashMap、CopyOnWriteArraySet。

    30.BlockingQueue是什么?

        Java.util.concurrent.BlockingQueue是一个队列,在进行检索或移除一个元素的时候,它会等待队列变为非空;当在添加一个元素时,它会等待队列中的可用空间。BlockingQueue接口是Java集合框架的一部分,主要用于实现生产者-消费者模式。我们不需要担心等待生产者有可用的空间,或消费者有可用的对象,因为它都在BlockingQueue的实现类中被处理了。Java提供了集中BlockingQueue的实现,比如ArrayBlockingQueue、LinkedBlockingQueue、PriorityBlockingQueue,、SynchronousQueue等。

    31.队列和栈是什么,列出它们的区别?

        栈和队列两者都被用来预存储数据。java.util.Queue是一个接口,它的实现类在Java并发包中。队列允许先进先出(FIFO)检索元素,但并非总是这样。Deque接口允许从两端检索元素。

    栈与队列很相似,但它允许对元素进行后进先出(LIFO)进行检索。

        Stack是一个扩展自Vector的类,而Queue是一个接口。

    32.Collections类是什么?

        Java.util.Collections是一个工具类仅包含静态方法,它们操作或返回集合。它包含操作集合的多态算法,返回一个由指定集合支持的新集合和其它一些内容。这个类包含集合框架算法的方法,比如折半搜索、排序、混编和逆序等。

    33.Comparable和Comparator接口是什么?

        如果我们想使用Array或Collection的排序方法时,需要在自定义类里实现Java提供Comparable接口。Comparable接口有compareTo(T OBJ)方法,它被排序方法所使用。我们应该重写这个方法,如果“this”对象比传递的对象参数更小、相等或更大时,它返回一个负整数、0或正整数。但是,在大多数实际情况下,我们想根据不同参数进行排序。比如,作为一个CEO,我想对雇员基于薪资进行排序,一个HR想基于年龄对他们进行排序。这就是我们需要使用Comparator接口的情景,因为Comparable.compareTo(Object o)方法实现只能基于一个字段进行排序,我们不能根据对象排序的需要选择字段。Comparator接口的compare(Object o1, Object o2)方法的实现需要传递两个对象参数,若第一个参数比第二个小,返回负整数;若第一个等于第二个,返回0;若第一个比第二个大,返回正整数。

    34.Comparable和Comparator接口有何区别?

        Comparable和Comparator接口被用来对对象集合或者数组进行排序。Comparable接口被用来提供对象的自然排序,我们可以使用它来提供基于单个逻辑的排序。

        Comparator接口被用来提供不同的排序算法,我们可以选择需要使用的Comparator来对给定的对象集合进行排序。

    35.我们如何对一组对象进行排序?

        如果我们需要对一个对象数组进行排序,我们可以使用Arrays.sort()方法。如果我们需要排序一个对象列表,我们可以使用Collection.sort()方法。两个类都有用于自然排序(使用Comparable)或基于标准的排序(使用Comparator)的重载方法sort()。Collections内部使用数组排序方法,所有它们两者都有相同的性能,只是Collections需要花时间将列表转换为数组。

    36.当一个集合被作为参数传递给一个函数时,如何才可以确保函数不能修改它?

        在作为参数传递之前,我们可以使用Collections.unmodifiableCollection(Collection c)方法创建一个只读集合,这将确保改变集合的任何操作都会抛出UnsupportedOperationException。

    37.我们如何从给定集合那里创建一个synchronized的集合?

        我们可以使用Collections.synchronizedCollection(Collection c)根据指定集合来获取一个synchronized(线程安全的)集合。

    38.集合框架里实现的通用算法有哪些?

        Java集合框架提供常用的算法实现,比如排序和搜索。Collections类包含这些方法实现。大部分算法是操作List的,但一部分对所有类型的集合都是可用的。部分算法有排序、搜索、混编、最大最小值。

    39.大写的O是什么?举几个例子?

        大写的O描述的是,就数据结构中的一系列元素而言,一个算法的性能。Collection类就是实际的数据结构,我们通常基于时间、内存和性能,使用大写的O来选择集合实现。比如:例子1:ArrayList的get(index i)是一个常量时间操作,它不依赖list中元素的数量。所以它的性能是O(1)。例子2:一个对于数组或列表的线性搜索的性能是O(n),因为我们需要遍历所有的元素来查找需要的元素。

    40.与Java集合框架相关的有哪些最好的实践?

    (1)根据需要选择正确的集合类型。比如,如果指定了大小,我们会选用Array而非ArrayList。如果我们想根据插入顺序遍历一个Map,我们需要使用TreeMap。如果我们不想重复,我们应该使用Set。

    (2)一些集合类允许指定初始容量,所以如果我们能够估计到存储元素的数量,我们可以使用它,就避免了重新哈希或大小调整。

    (3)基于接口编程,而非基于实现编程,它允许我们后来轻易地改变实现。

    (4)总是使用类型安全的泛型,避免在运行时出现ClassCastException。

    (5)使用JDK提供的不可变类作为Map的key,可以避免自己实现hashCode()和equals()。

    (6)尽可能使用Collections工具类,或者获取只读、同步或空的集合,而非编写自己的实现。它将会提供代码重用性,它有着更好的稳定性和可维护性。

     

     

    展开全文
  • 数组和集合的区别

    万次阅读 多人点赞 2018-06-24 09:19:39
    数组和集合的定义一、数组数组是java语言内置的数据类型,他是一个线性的序列,所有可以快速访问其他的元素,数组和其他语言不同,当你创建了一个数组时,他的容量是不变的,而且在生命周期也是不能改变的,还有JAVA...

    数组和集合的定义

    一、数组

    数组是java语言内置的数据类型,他是一个线性的序列,所有可以快速访问其他的元素,数组和其他语言不同,当你创建了一个数组时,他的容量是不变的,而且在生命周期也是不能改变的,还有JAVA数组会做边界检查,如果发现有越界现象,会报RuntimeException异常错误,当然检查边界会以效率为代价。

    二、集合

    JAVA还提供其他集合,list,map,set,他们处理对象的时候就好像这些对象没有自己的类型一样,而是直接归根于Object,这样只需要创建一个集合,把对象放进去,取出时转换成自己的类型就行了。

    三、数组和集合的区别

    一、数组声明了它容纳的元素的类型,而集合不声明。

    二、数组是静态的,一个数组实例具有固定的大小,一旦创建了就无法改变容量了。而集合是可以动态扩展容量,可以根据需要动态改变大小,集合提供更多的成员方法,能满足更多的需求。

    三、数组的存放的类型只能是一种(基本类型/引用类型),集合存放的类型可以不是一种(不加泛型时添加的类型是Object)

    四、数组是java语言中内置的数据类型,是线性排列的,执行效率或者类型检查都是最快的。

    集合体系结构

    Collection
    ├List (有序集合,允许相同元素和null)
    │├LinkedList (非同步,允许相同元素和null,遍历效率低插入和删除效率高)
    │├ArrayList (非同步,允许相同元素和null,实现了动态大小的数组,遍历效率高,用的多)
    │└Vector(同步,允许相同元素和null,效率低)
    │ └Stack(继承自Vector,实现一个后进先出的堆栈)
    └Set (无序集合,不允许相同元素,最多有一个null元素)

         |-HashSet(无序集合,不允许相同元素,最多有一个null元素)

       

     


    Map (没有实现collection接口,key不能重复,value可以重复,一个key映射一个value)
    ├Hashtable (实现Map接口,同步,不允许null作为key和value,用自定义的类当作key的话要复写hashCode和eques方法,)
    ├HashMap (实现Map接口,非同步,允许null作为key和value,用的多)
    └WeakHashMap(实现Map接口)


    Collection接口
      Collection是最基本的集合接口,一个Collection代表一组Object,即Collection的元素(Elements)。一些Collection允许相同的元素而另一些不行。一些能排序而另一些不行。Java SDK不提供直接继承自Collection的类,Java SDK提供的类都是继承自Collection的“子接口”如List和Set。
      所有实现Collection接口的类都必须提供两个标准的构造函数:无参数的构造函数用于创建一个空的Collection,有一个Collection参数的构造函数用于创建一个新的Collection,这个新的Collection与传入的Collection有相同的元素。后一个构造函数允许用户复制一个Collection。
      如何遍历Collection中的每一个元素?不论Collection的实际类型如何,它都支持一个iterator()的方法,该方法返回一个迭代子,使用该迭代子即可逐一访问Collection中每一个元素。典型的用法如下:
       Iterator it = collection.iterator(); // 获得一个迭代子
        while(it.hasNext()) {
          Object obj = it.next(); // 得到下一个元素
        }
      Collection接口派生的两个接口是ListSet

    一、List接口

     List是有序的Collection,使用此接口能够精确的控制每个元素插入的位置。用户能够使用索引(元素在List中的位置,类似于数组下标)来访问List中的元素,这类似于Java的数组。
    和下面要提到的Set不同,List允许有相同的元素。
      除了具有Collection接口必备的iterator()方法外,List还提供一个listIterator()方法,返回一个ListIterator接口,和标准的Iterator接口相比,ListIterator多了一些add()之类的方法,允许添加,删除,设定元素,还能向前或向后遍历。
      实现List接口的常用类有LinkedList,ArrayList,Vector和Stack。

    LinkedList类
     LinkedList实现了List接口,允许null元素。LinkenList底层采用了双向链表来存储数据,每个节点都存储着上一个节点和下一个节点的地址以及本节点的数据。此外LinkedList提供额外的get,remove,insert方法在LinkedList的首部或尾部。这些操作使LinkedList可被用作堆栈(stack),队列(queue)或双向队列(deque)。
      注意:LinkedList没有同步方法。如果多个线程同时访问一个List,则必须自己实现访问同步。一种解决方法是在创建List时构造一个同步的List:
        List list = Collections.synchronizedList(new LinkedList(...));
    ArrayList类
     
     ArrayList实现了可变大小的数组。它允许所有元素,包括null。ArrayList底层采用动态数组的存储方式,便利效率非常高,ArrayList是线程不安全的。
    size,isEmpty,get,set方法运行时间为常数。但是add方法开销为分摊的常数,添加n个元素需要O(n)的时间。其他的方法运行时间为线性。
      每个ArrayList实例都有一个容量(Capacity),即用于存储元素的数组的大小。这个容量可随着不断添加新元素而自动增加,但是增长算法并没有定义。当需要插入大量元素时,在插入前可以调用ensureCapacity方法来增加ArrayList的容量以提高插入效率。

    ArrayList和LindedList的区别:
            1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。 
         2.对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。 
         3.对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。 

    Vector类
     
     Vector非常类似ArrayList,但是Vector是同步的。由Vector创建的Iterator,虽然和ArrayList创建的Iterator是同一接口,但是,因为Vector是同步的,当一个Iterator被创建而且正在被使用,另一个线程改变了Vector的状态(例如,添加或删除了一些元素),这时调用Iterator的方法时将抛出ConcurrentModificationException,因此必须捕获该异常。
    Stack 类
      Stack继承自Vector,实现一个后进先出的堆栈。Stack提供5个额外的方法使得Vector得以被当作堆栈使用。基本的push和pop方法,还有peek方法得到栈顶的元素,empty方法测试堆栈是否为空,search方法检测一个元素在堆栈中的位置。Stack刚创建后是空栈。

    二、Set接口
    Set是一种无序的并且不包含重复的元素的Collection,即任意的两个元素e1e2都有e1.equals(e2)=falseSet最多有一个null元素
      很明显,Set的构造函数有一个约束条件,传入的Collection参数不能包含重复的元素。

    HashSet 类

    是哈希表实现的,HashSet中的数据是无序的,可以放入null,但只能放入一个null,两者中的值都不能重复,因为HashSet的底层实现是HashMap,但是HashSet只使用了HashMap的key来存取数据所以HashSet存的数据不能重复。 

    HashSet要求放入的对象必须实现HashCode()方法,放入的对象,是以hashcode码作为标识的,而具有相同内容的 String对象,hashcode是一样,所以放入的内容不能重复。但是同一个类的对象可以放入不同的实例 。


    三、Map接口
    Map没有继承Collection接口Map提供keyvalue的映射。一个Map中不能包含相同的key,每个key只能映射一个valueMap接口提供3种集合的视图,Map的内容可以被当作一组key集合,一组value集合,或者一组key-value映射。

    Hashtable类
    Hashtable继承Map接口,实现一个key-value映射的哈希表。任何非空(non-null)的对象都可作为key或者value
      添加数据使用put(key, value),取出数据使用get(key),这两个基本操作的时间开销为常数。

    使用Hashtable的简单示例如下,将123放到Hashtable中,他们的key分别是”one””two””three”
    Hashtable numbers = new Hashtable();
    numbers.put(“one”, new Integer(1));
    numbers.put(“two”, new Integer(2));
    numbers.put(“three”, new Integer(3));
      要取出一个数,比如2,用相应的key
    Integer n = (Integer)numbers.get(“two”);
    System.out.println(“two = ” + n);
      由于作为key的对象将通过计算其散列函数来确定与之对应的value的位置,因此任何作为key的对象都必须实现hashCodeequals方法。hashCodeequals方法继承自根类Object,如果你用自定义的类当作key的话,要相当小心,按照散列函数的定义,如果两个对象相同,即obj1.equals(obj2)=true,则它们的hashCode必须相同,但如果两个对象不同,则它们的hashCode不一定不同,如果两个不同对象的hashCode相同,这种现象称为冲突,冲突会导致操作哈希表的时间开销增大,所以尽量定义好的hashCode()方法,能加快哈希表的操作。
      如果相同的对象有不同的hashCode,对哈希表的操作会出现意想不到的结果(期待的get方法返回null),要避免这种问题,只需要牢记一条:要同时复写equals方法和hashCode方法,而不要只写其中一个。
      Hashtable是同步的。


    HashMap类

    HashMapHashtable类似,不同之处在于HashMap是非同步的,并且允许null,即null valuenull key,但是将HashMap视为Collection时(values()方法可返回Collection)。
    WeakHashMap类
    WeakHashMap是一种改进的HashMap,它对key实行弱引用,如果一个key不再被外部所引用,那么该key可以被GC回收。

    总结
    1.如果涉及到堆栈,队列等操作,应该考虑用List,对于需要快速插入,删除元素,应该使用LinkedList,如果需要快速随机访问元素,应该使用ArrayList。
    2.如果程序在单线程环境中,或者访问仅仅在一个线程中进行,考虑非同步的类,其效率较高,如果多个线程可能同时操作一个类,应该使用同步的类。
    3.要特别注意对哈希表的操作,作为key的对象要正确复写equals和hashCode方法。
    4.尽量返回接口而非实际的类型,如返回List而非ArrayList,这样如果以后需要将ArrayList换成LinkedList时,客户端代码不用改变。这就是针对抽象编程。

    展开全文
  • 求解集合A和集合B的差集

    千次阅读 2017-07-25 20:43:24
    求解集合A和集合B的差集 题目:已知集合A和B的元素分别用不含头结点的单链表存储,函数difference()用于求解集合A与B的差集,并将结果保存在集合A的单链表中。例如,若集合A={5,10,20,15,25,30},集合B={5,15,35,25...

    求解集合A和集合B的差集

    题目:已知集合A和B的元素分别用不含头结点的单链表存储,函数difference()用于求解集合A与B的差集,并将结果保存在集合A的单链表中。例如,若集合A={5,10,20,15,25,30},集合B={5,15,35,25},完成计算后A={10,20,30}。

    算法思想:取出集合A中每一个元素,与集合B中对比,找到即可删除此节点,否则保留。
    prev实现删除节点后的连接
    当prev=NULL时,说明是首次找到A和B的公有元素,此时*LA指向pa->next,*LA仍然是头结点;
    当prev!=NULL时,prev指向pa->next,实现删除结点的链接。
    代码实现:
    #include 
    #include 
    #include 
    typedef struct ListNode
    {
    	int elem;
    	struct ListNode* next;
    }Node,*pNode,*pList;
    
    void Init(pList* pplist)
    {
    	assert(pplist);
    	*pplist = NULL;
    }
    pNode BuyNode(int x)
    {
    	pNode cur = (pNode)malloc(sizeof(Node));
    	if (cur == NULL)
    	{
    		perror("malloc");
    		return NULL;
    	}
    	cur->elem = x;
    	cur->next = NULL;
    	return cur;
    }
    void Push(pList* pplist, int x)
    {
    	pNode NewNode = BuyNode(x);
    	if (*pplist == NULL)
    	{
    		*pplist = NewNode;
    	}
    	
    	else
    	{
    		pNode cur = *pplist;
    		while (cur->next)
    		{
    			cur = cur->next;
    		}
    		 cur->next = NewNode;
    	}
    }
    
    void Print(pList plist)
    {
    	pNode cur = plist;
    	while (cur)
    	{
    		printf("%d ", cur->elem);
    		cur = cur->next;
    	}
    	printf("NULL\n");
    }
    
    void difference(pNode* LA, pNode LB)
    {
    	pNode pa, pb, q;
    	pNode prev = NULL;
    	pa = *LA;               //*LA是指向指针的指针,pa指向集合的元素
    	while (pa)
    	{
    		pb = LB;            //pb指向集合的元素
    		while (pb && pa->elem != pb->elem)
    			pb = pb->next;
    		if (pb)             //pa所指向元素与pb所指的元素相等
    		{
    			if (!prev)
    			{
    				*LA = pa->next;
    			}
    			else
    			{
    				prev->next = pa->next;
    			}
    			q = pa;          //求差集,即删除pa结点
    			pa = pa->next;
    			free(q);
    		}
    		else
    		{
    			prev = pa;
    			pa = pa->next;
    		}
    	}
    }
    
    
    void Test()
    {
    	pList plist1;
    	Init(&plist1);
    	Push(&plist1, 12);
    	Push(&plist1, 2);
    	Push(&plist1, 92);
    	Push(&plist1, 1);
    	Push(&plist1, 11);
    	Print(plist1);
    
    	pList plist2;
    	Init(&plist2);
    	Push(&plist2, 12);
    	Push(&plist2, 21);
    	Push(&plist2, 92);
    	Push(&plist2, 1);
    	Print(plist2);
    	difference(&plist1, plist2);
    	Print(plist1);
    
    }
    测试结果:


    展开全文
  • 之前的文章中,我们使用JOL工具简单的分析过String,数组和集合类的内存占用情况,这里再做一次更详细的分析和介绍,希望大家后面再遇到OOM问题的时候不再抱头痛哭,而是可以有章可循,开始吧。 数组 先看下JOL的代码...

    简介

    之前的文章中,我们使用JOL工具简单的分析过String,数组和集合类的内存占用情况,这里再做一次更详细的分析和介绍,希望大家后面再遇到OOM问题的时候不再抱头痛哭,而是可以有章可循,开始吧。

    数组

    先看下JOL的代码和输出:

    //byte array
    log.info("{}",ClassLayout.parseInstance("www.flydean.com".getBytes()).toPrintable());
    

    输出结果:

    INFO com.flydean.CollectionSize - [B object internals:
     OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
          0     4        (object header)                           01 00 00 00 (00000001 00000000 00000000 00000000) (1)
          4     4        (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
          8     4        (object header)                           22 13 07 00 (00100010 00010011 00000111 00000000) (463650)
         12     4        (object header)                           0f 00 00 00 (00001111 00000000 00000000 00000000) (15)
         16    15   byte [B.<elements>                             N/A
         31     1        (loss due to the next object alignment)
    Instance size: 32 bytes
    Space losses: 0 bytes internal + 1 bytes external = 1 bytes total
    

    注意,本文的结论都在64位的JVM中运行得出了,并且开启了COOPs压缩对象指针技术。

    可以看到数组对象的对象头大小是16字节,再加上数组里面的内容长度是15字节,再加上1位补全。最后得到的大小是32字节。

    同样的,我们计算存有100个对象的数组,可以得到下面的结论:

    注意最后面的Object数组,如果数组中存储的不是基础类型,那么实际上存储的是执行该对象的指针,该指针大小是4个字节。

    String

    String是一个非常特殊的对象,它的底层是以byte数组存储的。

    注意,在JDK9之前,String的底层存储结构是char[],一个char需要占用两个字节的存储单位。

    因为大部分的String都是以Latin-1字符编码来表示的,只需要一个字节存储就够了,两个字节完全是浪费。

    于是在JDK9之后,字符串的底层存储变成了byte[]。

    同样的我们还是用JOL来分析:

    //String
    log.info("{}",ClassLayout.parseInstance("www.flydean.com").toPrintable());
    

    输出结果:

    INFO com.flydean.CollectionSize - java.lang.String object internals:
     OFFSET  SIZE      TYPE DESCRIPTION                               VALUE
          0     4           (object header)                           05 00 00 00 (00000101 00000000 00000000 00000000) (5)
          4     4           (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
          8     4           (object header)                           77 1a 06 00 (01110111 00011010 00000110 00000000) (399991)
         12     4    byte[] String.value                              [119, 119, 119, 46, 102, 108, 121, 100, 101, 97, 110, 46, 99, 111, 109]
         16     4       int String.hash                               0
         20     1      byte String.coder                              0
         21     1   boolean String.hashIsZero                         false
         22     2           (loss due to the next object alignment)
    Instance size: 24 bytes
    Space losses: 0 bytes internal + 2 bytes external = 2 bytes total
    

    可以看到String中的对象头是12字节,然后加上4字节的指针指向一个byte数组。再加上hash,coder,和hasIsZero属性,最后的大小是24字节。

    我这里使用的是JDK14的String版本,不同的版本可能有所不同。

    当然这只是这个String对象的大小,不包含底层数组的大小。

    我们来计算一下String对象的真实大小:

    String对象的大小+byte数组的大小=24+32=56字节。

    ArrayList

    我们构建一个非常简单的ArrayList:

    //Array List
    log.info("{}",ClassLayout.parseInstance(new ArrayList()).toPrintable());
    

    输出结果:

    INFO com.flydean.CollectionSize - java.util.ArrayList object internals:
     OFFSET  SIZE                 TYPE DESCRIPTION                               VALUE
          0     4                      (object header)                           05 00 00 00 (00000101 00000000 00000000 00000000) (5)
          4     4                      (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
          8     4                      (object header)                           87 81 05 00 (10000111 10000001 00000101 00000000) (360839)
         12     4                  int AbstractList.modCount                     0
         16     4                  int ArrayList.size                            0
         20     4   java.lang.Object[] ArrayList.elementData                     []
    Instance size: 24 bytes
    Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
    

    画个图来直观的表示:

    这里modCount和size的初始值都是0。

    HashMap

    因为文章篇幅的限制,这里就不把代码列出来了,我只贴个图上来:

    HashSet

    LinkedList

    treeMap

    来个比较复杂的TreeMap:

    总结

    本文用图形的形式形象的展示了集合对象,数组和String在内存中的使用情况。

    后面的几个集合我就没有一一计算,有兴趣的朋友可以在下方回复你计算的结果哟。

    本文作者:flydean程序那些事

    本文链接:http://www.flydean.com/jvm-collections-size/

    本文来源:flydean的博客

    欢迎关注我的公众号:程序那些事,更多精彩等着您!

    展开全文
  • 字典和集合

    千次阅读 2018-09-08 18:17:13
    集合:是无序的,不支持下标索引,它是可变的数据类型,集合中的元素是唯一的,一般...4.集合只支持成员操作符for循环 5.集合的常用方法 1)增加 2)删除 3)交集、并集、差集 4)对等差分 5)判断...
  • js数组和集合互转

    千次阅读 2018-12-06 22:29:00
    js数组和集合互转可用于去重: 数组转集合 var arr = [55, 44, 65]; var set = new Set(arr); console.log(set.size === arr.length); console.log(set.has(65)); 集合转数组 var set = new Set([1, 2, 3...
  • List数组和集合相互转换

    千次阅读 2018-05-09 16:58:48
    List数组和集合相互转换1、List的toArray()方法用于将集合转换成数组,但实际上改方法是在Collection中定义的,所以所有的集合都具备这个功能, 其有两个方法:Object【】 toArray() 和 T&lt;T&gt; [] ...
  • Java打印输出数组和集合

    万次阅读 2016-09-01 12:37:11
    Java打印输出数组和集合 在java中是可以直接打印输出数组和集合的,不需要我们编写循环来打印输出。 数组可以通过Arrays.toString(int[] )函数来输出;而因为List Set Map等集合类都实现了toString()方法,所以...
  • 处理JS中定义对象和集合

    千次阅读 2017-08-25 14:30:45
    JS中定义对象和集合 在js中定义对象:var obj = {};  obj['a']=1;  obj['b']=2; 在js中定义集合:var list = [];  list.push(obj);
  • Python基础六:字典和集合

    千次阅读 2018-05-11 09:17:41
    Python基础六:字典和集合 Python基础系列内容为学习廖雪峰老师Python3教程的记录,廖雪峰老师官网地址:廖雪峰Python3教程 Author:yooongchun Email:yooongchun@foxmail.com dict :Python内置一种字典...
  • java中的集合和集合的选择

    千次阅读 多人点赞 2018-03-27 00:25:56
    一、java中的集合介绍 学习东西,首先要知道学习他有什么用,他能够带给我什么样的效果。只有知道什么时候用,怎么用,这样才会对我们有用处,不然百学浪费时间。本篇主要讲解java中的常使用的集合的简单对比,没有...
  • 数组和集合区别

    万次阅读 2018-09-04 14:07:38
    一、数组声明了它容纳的元素的类型,而集合不声明。  二、数组是静态的,一...而集合是可以动态扩展容量,可以根据需要动态改变大小,集合提供更多的成员方法,能满足更多的需求。  三、数组不论是效率还是类型...
  • 213维恩图和集合图(Venn&Upset)

    千次阅读 2020-07-10 07:00:00
    维恩图和集合图本节作者:徐俊,北京大学人民医院版本1.0.5,更新日期:2020年6月30日本项目永久地址:https://github.com/YongxinLiu/Microbiom...
  • 探讨LoadRunner的并发用户和集合

    千次阅读 2013-12-10 10:24:21
    近来跟踪一个项目,发现同事们在执行...当前我并反对这个观点,不过却让我有一种疑虑,促使我想更深入的理解并发用户和集合点,我相信大多数进入性能测试研究领域的朋友都应该有疑惑,主要原因我觉得还是由于不能深入理
  • 数据可视化-Tableau-组和集合

    千次阅读 2018-05-08 20:53:21
    和集合 Tableau 有两种将数据组合到一起的方法:组和集合。它们比较相似,但是也有差别,我将详细介绍。 将数据点组合到一起可以帮助传达你的观点。例如,如果你要指出亏损的产品,可以创建一个此类产品组,然后...
  • 一、集合的表示 列举法:列出集合中的全体元素,元素之间用逗号分开,然后用花括号括起来 描述法:用谓词P(x)表示x具有性质P,用{x|P(x)}表示具有性质P的集合 注意事项:集合中的元素是各不相同的 ​ 集合...
  • Mongodb 数据库创建集合主要使用的指令为:db.createCollection()函数,相关函数说明,请参考其他文献资料。 如下: 选择在指定的数据库中创建集合。 -- show dbs ; 查询当前mongodb 所包含的数据库实列。 ...
  • 使用JackSon将对象和集合转为Json

    千次阅读 2016-10-02 14:02:34
    使用JackSon将对象和集合转为Json首先三个jar demopackage com.xieth.test;import java.util.Arrays; import java.util.List; import com.fasterxml.jackson.core.JsonProcessingException; import ...
  • Java 数组和集合的区别

    千次阅读 2019-07-05 22:16:43
    目录 相同点 存储元素的区别 : 长度的区别: 使用选择 ...集合和数组都是Java中的容器。...1.1,数组既可以存储基本数据类型,...1.2,集合只能存储引用数据类型(对象)集合中也可以存储基本数据类型,但是在存储的时候会...
  • kotlin数组和集合

    千次阅读 2019-03-11 11:30:55
    一、Kotlin数组 1.对象数组 由Kotlin的main函数的写法,可以看出Kotlin中的对象数组...(1)使用arrayOf函数指定的数组元素创建数组 //Java写法: String[]params1={"str1","str2","str...
  • mybatis 高级关联和集合映射:嵌套查询和嵌套结果小案例,帮助更好的理解关联和集合的使用
  • springboot+GRPC传输流式数据和集合对象概述项目结构和实现步骤demo实现接口文件部分服务端客户端运行结果 概述 整个demo是在上一篇springboot+GRPC传输简单数据的基础上添加的内容,如有什么不明白的地方可参考上一...
  • 数组、链表等常用数据结构和集合浅解(java)

    万次阅读 多人点赞 2017-04-21 20:23:38
    数组、链表等常用数据结构和集合浅解(java)脑子转了一圈,巴拉巴拉的写了一大堆,本来今天步行者打骑士的比赛在上半场已经花了,步行者领先20多分,然而詹姆斯一个大大大号三双强行把比分拉回来还赢了比赛,留下36...
  • <!-- https://mvnrepository.com/artifact/net.sf.json-lib/json-lib --> <dependency> <groupId>net.sf.json-lib</groupId> <artifactId>json-lib</artifactId>...
  • java 字符串和集合互相转换

    万次阅读 2018-03-29 23:40:46
    今天在写项目的时候遇到一个问题,就是要把得到的一个集合转换成字符串,发现 import org.apache.commons.lang.StringUtils; 有这么一个简单的方法:String str=StringUtils.join(list,","); 第一个...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 305,234
精华内容 122,093
关键字:

和集合