JAVA篇:Java集合框架
我曾做下一周一篇的计划,然而另一篇章的进行实在很不顺利,甚至有一章涂涂改改多次后感觉还是不对劲想要推翻重新写,所以用Java篇来混更了……
只是很多知识点其实已经有不少大佬已经有比较详尽、准确的概括了,毕竟自己水平也不怎么够,我所做的其实只是在整理以及逐字打下大佬的观点时整理自己的知识点。
1、java集合整体框架
Java集合框架主要包含两种类型的容器,一种是集合(Collection),存储一个元素几个,另一种是图(Map),存储键/值对映射。Collection接口又有3种子类型,List、Set和Queue,再下面是一些抽象类,最后是具体实现类,常用的有ArrayList、Linked、List、HashSet、LinkedHashSet、HashMap、LinkedHashMap等等。
2、Iterator接口
java.util.Iterator
该接口是Collection对象的迭代器,是遍历集合的工具。Collection依赖于Iterator,Collection的实现类都要实现iterator()函数返回一个iterator对象,其中的ListIterator是专门为遍历List而存在的。Iterator取代了Java Collections Framework种的Enumeration。
/* Iterator */ Integer[] arr = {1,2,3,4,5}; List<Integer> list = Arrays.asList(arr); Iterator<Integer> iterator = list.iterator(); while (iterator.hasNext()){ System.out.print(iterator.next()+" ");//1 2 3 4 5 } System.out.println(); ListIterator<Integer> literator = list.listIterator(2); while (literator.hasNext()){ System.out.print(literator.next()+" ");//3 4 5 } System.out.println();
3、Collection接口
java.util.Collection
是一个集合框架的父接口,它提供了对集合对象进行基本操作的通用接口方法。Collection接口的重要子接口包括List、Set和Queue,Map并不是Collection的子接口。
4、List接口
java.util.List
列表是有序的collection(也称为序列)。此接口的用户可以对列表中每个元素的插入位置进行精确的控制。用户可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素。列表通常允许重复的元素。
List接口在iterator、add、remove、equals和hashCode方法的协定上加了一些其他的约定,List接口提供了4种对列表元素进行定位(索引)访问方法,提供了特殊的迭代器ListIterator(允许元素插入和替换,以及双向访问),提供了两种搜索指定对象的方法,提供了两种在列表的任一位置高效插入和溢出多个元素的方法。
具体方法见:
List接口有四个重要的实现类:ArrayList、LinkedList\Vector、Stack。
4.1 ArrayList类
java.util.AbstractList<E>
提供了List接口的骨干实现,以最大限度地减少实现“随机访问”数据存储(如数组)支持的该接口 所需的工作。对于连续访问的数据应优先使用LinkedList而不是此类。
ArrayList是一个动态数组,也是我们最常用的集合,它允许任何符合规则的元素的插入甚至包括null。每一个ArrayList都有一个初始容量(10),该容量代表了数组的大小。容器种的元素不断增加,容器的大小也会随着增加。在每次向容器种增加元素的同时都会进行容量检查,当快溢出时,就会进行扩容操作。所以如果我们明确所插入元素的大小,最好指定一个初始容量值,避免过多的进行扩容操作而浪费时间、效率。
ArrayList擅长于随机访问,同时ArrayList是非同步的。
具体方法见:
数组与ArrayList
数组在内存中是连续的,所以它的索引速度是非常的快,而且赋值与修改元素也很简单。但是数组需要一开始就确定长度,并且在两个数据建插入数据很麻烦,由此引入了Array List。
a)列表转换成数组的方法
/* List转为数组 */ List<Integer> alist = new ArrayList<Integer>(); alist.add(12); alist.add(13); //List提供了toArray的接口可以直接转为object类型的数组 //但是该方法存在强制类型转换时会抛出异常 Object[] objects = alist.toArray(); //可以指定类型以及数组长度 Integer[] a = alist.toArray(new Integer[alist.size()]); System.out.println(a[0]+" "+a[1]);//12 13
b)数组转换成列表的方法
/*数组转换为list*/ Integer[] arr = {1,2,3,4,5}; //1、该方法存在弊端,返回的list时Arrays里面的一个静态内部类,该类未实现add,remove方法,因此在使用时存在局限性 List<Integer> list1 = Arrays.asList(arr); / list1.remove(1);//java.lang.UnsupportedOperationException System.out.println(list1); //2、可以使用ArrayList的构造方法 List<Integer> list2 = new ArrayList<>(Arrays.asList(arr)); list2.remove(1); System.out.println(list2); //3、运用collections的addAll方法 List<Integer> list3 = new ArrayList<>(arr.length); Collections.addAll(list3,arr); System.out.println(list3);
4.2 LinkedList类
java.util.LinkedList
是List接口的链接列表实现,实现所有可选的列表操作,同时也也实现了Deque接口,为add、poll提供先进先出队列操作,以及其他堆栈和双端队列操作。
LinkedList是一个双向链表,其实现机制与ArrayList完全不同,其随机访问集合中的元素性能比较差,但在插入删除元素时有较好的性能。同时,LinkedList也是非同步的。
具体方法见:
4.3 Vector类
Vector类可以实现可增长的对象数组,与ArrayList相似,但是Vector时同步的,是线程安全的动态数组,它的操作与ArrayList几乎一样。
具体方法见:
4.4 Stack类
java.util.Stack
表示后进先出(LIFO)的对象堆栈,它继承自Vector。
具体方法见:
5 Set接口
java.util.Set
是一个不包含重复元素的collection。它维持它自己的内部排序,所以随机访问没有任何意义。
Set接口有三个具体实现类,分别是散列集HashSet、链式散列集LinkedHashSet和树形集TreeSet。
5.1 HashSet类
java.util.HasSet
是set集合最常用的实现类,是其经典实现。HashSet是按照hash算法来存储元素的,因此具有很好的存取和查找性能。其具有如下特点:
-
不能保证元素的顺序:一是元素插入顺序和输出顺序不能保证一致,而元素存储位置由其哈希值决定,是固定的。
-
HashSet不是线程同步的,如果多线程操作HashSet集合,则应通过代码来保证其同步。
-
集合元素值可以是null,但仅能有一个null值。
具体方法见:
5.2 LinkedHashSet类
java.util.LinkedHashSet
具有可预知迭代顺序的 Set 接口的哈希表和链接列表实现。此实现与 HashSet 的不同之外在于,后者维护着一个运行于所有条目的双重链接列表。此链接列表定义了迭代顺序,即按照将元素插入到 set 中的顺序(插入顺序)进行迭代。注意,插入顺序不 受在 set 中重新插入的 元素的影响。
LinkedHashSet是HashSet的一个子类,具有HashSet的特性,但是它使用链表维护元素的次序,元素的顺序与添加顺序一致。由于LinkedHashSet需要维护元素的插入顺序,因此性能略低于HashSet,但在迭代访问Set里的全部元素时有很好的性能。
具体方法见:
5.3 TreeSet类
java.util.TreeSet
是基于TreeMap的NavigableSet的实现,非线程安全。使用元素的自然顺序,或者根据创建set时提供的Comparator进行排序,具体取决使用的构造方法。
具体方法见:
6 Map接口
Map接口与List、Set接口不同,它是由一系列键值对组成的集合,提供了key到value的映射。同时它也没有继承Collection,在Map中它保证的key和value之间的一一对应关系。也就是说一个key对应一个value,所以它不能存在相同的key值,当然value值可以相同。
Map接口包含重要的嵌套接口Map.Entry<K,V>,以及三个具体实现类HashMap、LinkedHashMap和TreeMap。
6.1 HashMap
java.util.HashMap
是基于哈希表的Map接口的实现。此实现提供所有可选的映射操作,并允许使用null值和null键。除了非同步和允许使用null之外,HashMap类与Hashtable大致相同,此类不保证映射的顺序,特别是它不保证该顺序恒久不变。
具体方法见:
6.2 LinkedHashMap
java.util.LinkedHashMap
是HashMap的一个子类,它保留插入的顺序,如果需要输出的顺序和输入时的相同,那么就选用LinkedHashMap。
LinkedHashMap维护着一个运行于所有条目的双重链接列表,此链接列表定义了迭代顺序,该迭代顺序可以是插入顺序或者是访问顺序。
具体方法见:
6.3 TreeMap
TreeMap 是一个有序的key-value集合,非同步,基于红黑树(Red-Black tree)实现,每一个key-value节点作为红黑树的一个节点。TreeMap存储时会进行排序的,会根据key来对key-value键值对进行排序,其中排序方式也是分为两种,一种是自然排序,一种是定制排序,具体取决于使用的构造方法。
-
自然排序:TreeMap中所有的key必须实现Comparable接口,并且所有的key都应该是同一个类的对象,否则会报ClassCastException异常。
-
定制排序:定义TreeMap时,创建一个comparator对象,该对象对所有的treeMap中所有的key值进行排序,采用定制排序的时候不需要TreeMap中所有的key必须实现Comparable接口。
具体方法见:
7 总结
整理得很烦躁……或许是时间安排不对或许是这样子整理法不对吧。
参考