日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

数学知识巧学JCF(Java Collections framework)

發布時間:2023/12/18 java 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数学知识巧学JCF(Java Collections framework) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

 

 不知你是否還記得高中我們學過的集合,映射,函數,數學確實很牛逼,拿它來研究java集合類,輕而易舉的就把知識理解了。本篇文章適合初學java集合類的小白,也適合補充知識漏缺的學習者,同時也是面試者可以參考的一份資料。

數學知識

回顧一下之前所學的知識,結合我多年的高中數學教學經驗,相信你會對某些知識有一些新的感悟。

集合:一般地,我們把研究對象統稱為元素(element),把一些元素組成的總體叫做集合(set)。

對于一個給定的集合,其具有的特征:

確定性:集合中的元素都是確定的。

互異性:集合中的元素都是不同的。

無序性:集合中的元素的順序是無序的。

映射:一般地,我們有:

設A,B是兩個非空的集合,如果按照某一個確定的對應關系f.是對應集合A中的任意一個元素x,在集合B中都有唯一確定的元素y與之對應,那么就稱對應f:A—>B為集合A到集合B的一個映射(mapping)。

其實簡單的來講,何謂映射,就是函數上將的關系對應,例如:

函數 f(x)=x^2 ?那么每一個x都有唯一的y與之對應,這就是映射關系的一個模型。

而方程 x^2+y^2=1,這個很明顯是圓心為(0,0)的半徑為1的圓,任取一個x可能會有一個或者兩個y與之對應,這就不能稱為映射,進而不能稱為函數。(1,0)或者(-1,0)這時候的x只有唯一的確定的y和它對應。

集合類的學習

集合類產生的原因:在一般的情況下,我們在寫程序時并不知道將需要多少個對象,或者是否需要更加復雜的方式存儲對象,顯然使用具有固定長度的數組已經不能解決這個問題了。所以java 實用類庫提供了一套相當完整的容器類來解決這個問題。

基本概念

java容器類類庫的用途是“保存對象”,可將其劃分為兩個不同的概念:

1)collection.獨立元素的序列。主要包含List(序列),Set(集合),Queue(隊列)

List:按照插入的順序保存元素;

Set:不能有重復的元素;

Queue:按照排隊規則來確定對象產生的順序(通常與它們被插入的順序相同);

2)Map:一組成對的“鍵值對”對象,允許我們使用鍵來查找值。

針對經常使用的類庫,我們只列出List,Set,Map之間的繼承關系:

List

List接口在Collection的基礎上添加了大量的方法,使得可以在List的中間插入和刪除元素。

繼承自List的子類有ArrayList, ? LinkedList ,Vector三類。

list的特征:

1 有序的Collection 2 允許重復的元素,允許空的元素。 3 插入類似的數據:{1,2,4,{5,2},1,3};

ArrayList(類似于順序表)

其主要用于查找,對于刪除和插入,耗時巨大。ArrayList是以數組實現的列表,不支持同步。

優點:利用索引位置可以快速的定位訪問

? ?適合變動不大,主要用于查詢的數據

? ? ? ? ?和java的數組相比較,其容量是可以動態調整的。

? ? ?缺點:不適合指定位置的插入,刪除操作。

--ArrayList在元素填滿容器是會自動擴充容器大小的50%

ArrayListTest 代碼分析:

add()方法,添加元素,默認是在后面添加。

add(index,value),在指定索引處添加元素。會進行元素的移動。源碼如下:

1 public void add(int index, E element) { 2 rangeCheckForAdd(index); 3 ensureCapacityInternal(size + 1); // Increments modCount!! 4 System.arraycopy(elementData, index, elementData, index + 1, 5 size - index); 6 elementData[index] = element; 7 size++; 8 }

remove(index)刪除指定位置上的元素。源碼如下:

1 public E remove(int index) { 2 rangeCheck(index); 3 modCount++; 4 E oldValue = elementData(index); 5 int numMoved = size - index - 1; 6 if (numMoved > 0) 7 System.arraycopy(elementData, index+1, elementData, index, 8 numMoved); 9 elementData[--size] = null; // clear to let GC do its work 10 return oldValue; 11 }

  從源碼可以分析出,在ArrayList進行插入和刪除的時候,會進行類似順序表的操作,移動元素,空出位置,然后插入元素。刪除:依次移動后面的元素覆蓋指定位置的元素。這就會大大減慢ArrayList插入和刪除的效率。

舉一個應用的例子,更好的理解ArrayList:

1 public class ArrayListTest { 2 public static void main(String[] args) { 3 //泛型的用法,只允許Integer類型的元素插入。 4 ArrayList<Integer> arrayList =new ArrayList<Integer>(); 5 //增加元素 6 arrayList.add(2); 7 arrayList.add(3); 8 arrayList.add(4); 9 arrayList.add(5); 10 arrayList.add(4); 11 arrayList.add(null);//ArrayList允許空值插入, 12 arrayList.add(new Integer(3)); 13 System.out.println(arrayList);// [2, 3, 4, 5, 4, null, 3] 14 //查看元素的個數 15 System.out.println(arrayList.size());// 7 16 arrayList.remove(0); 17 System.out.println(arrayList);// [3, 4, 5, 4, null, 3] 18 arrayList.add(1, new Integer(9)); 19 System.out.println(arrayList);// [3, 9, 4, 5, 4, null, 3] 20 System.out.println("-----------遍歷方法-------"); 21 ArrayList<Integer> as=new ArrayList<Integer>(100000); 22 for(int i=0;i<100000;i++){ 23 as.add(i); 24 } 25 traverseByIterator(as); 26 traverseByFor(as); 27 traverseByForEach(as); 28 } 29 public static void traverseByIterator(ArrayList<Integer>al){ 30 System.out.println("---------迭代器遍歷-------------"); 31 long startTime=System.nanoTime();//開始時間 32 Iterator it=al.iterator(); 33 while(it.hasNext()){// 34 it.next(); 35 } 36 long endTime=System.nanoTime();//結束時間 37 System.out.println((endTime-startTime)+"納秒"); 38 } 39 public static void traverseByFor(ArrayList<Integer>al){ 40 System.out.println("---------索引遍歷-------------"); 41 long startTime=System.nanoTime();//開始時間 42 for(int i=0;i<al.size();i++) al.get(i); 43 long endTime=System.nanoTime();//結束時間 44 System.out.println((endTime-startTime)+"納秒"); 45 } 46 public static void traverseByForEach(ArrayList<Integer>al){ 47 System.out.println("---------Foreach遍歷-------------"); 48 long startTime=System.nanoTime();//開始時間 49 for(Integer temp:al); 50 long endTime=System.nanoTime();//結束時間 51 System.out.println((endTime-startTime)+"納秒"); 52 } 53 } 54 -----------遍歷方法------- 55 ---------迭代器遍歷------------- 56 10407039納秒 57 ---------索引遍歷------------- 58 7094470納秒 59 ---------Foreach遍歷------------- 60 9063813納秒 61 可以看到利用索引遍歷,相對來說是快一些。 View Code

迭代器 Iterator

1 hasNext() 判斷是否有下一個元素 2 next() 獲取下一個元素 3 remove () 刪除某個元素

LinkedList:(主要用于增加和修改!)

????--以雙向鏈表實現的列表,不支持同步。

????--可以被當做堆棧、隊列和雙端隊列進行操作

????--順序訪問高效,隨機訪問較差,中間插入和刪除高效

????--適合經常變化的數據

????addFirst()在頭部添加元素

????add(3,10);將10插入到第四個位置上

????remove(3)刪除第四個位置的元素

代碼詳解:

1 public class LinkedListTest { 2 public static void main(String[] args) { 3 LinkedList<Integer> linkedList=new LinkedList<Integer>(); 4 linkedList.add(2); 5 linkedList.add(3); 6 linkedList.add(9); 7 linkedList.add(6); 8 linkedList.add(7); 9 System.out.println(linkedList); 10 //linkedList.addFirst(1); 11 //linkedList.addLast(10); 12 //System.out.println(linkedList); 13 linkedList.add(3, 4); 14 System.out.println(linkedList); 15 System.out.println(linkedList.get(4)); 16 LinkedList<Integer> as=new LinkedList<Integer>(); 17 for(int i=0;i<100000;i++){ 18 as.add(i); 19 } 20 traverseByIterator(as); 21 traverseByFor(as); 22 traverseByForEach(as); 23 } 24 public static void traverseByIterator(LinkedList<Integer>al){ 25 System.out.println("---------迭代器遍歷-------------"); 26 long startTime=System.nanoTime();//開始時間 27 Iterator it=al.iterator(); 28 while(it.hasNext()){ 29 it.next(); 30 } 31 long endTime=System.nanoTime();//結束時間 32 System.out.println((endTime-startTime)+"納秒"); 33 } 34 public static void traverseByFor(LinkedList<Integer>al){ 35 System.out.println("---------索引遍歷-------------"); 36 long startTime=System.nanoTime();//開始時間 37 for(int i=0;i<al.size();i++) al.get(i); 38 long endTime=System.nanoTime();//結束時間 39 System.out.println((endTime-startTime)+"納秒"); 40 } 41 public static void traverseByForEach(LinkedList<Integer>al){ 42 System.out.println("---------Foreach遍歷-------------"); 43 long startTime=System.nanoTime();//開始時間 44 for(Integer temp:al); 45 long endTime=System.nanoTime();//結束時間 46 System.out.println((endTime-startTime)+"納秒"); 47 } 48 } 49 ---------迭代器遍歷------------- 50 6562423納秒 51 ---------索引遍歷------------- 52 4565606240納秒 53 ---------Foreach遍歷------------- 54 4594622納秒 55 可以看出使用索引遍歷,對于linkedList真的很費時間!

add(index,value)源碼分析:我們可以看到,這就是雙引用(雙指針)的賦值操作。

1 void linkBefore(E e, Node<E> succ) { 2 // assert succ != null; 3 final Node<E> pred = succ.prev; 4 final Node<E> newNode = new Node<>(pred, e, succ); 5 succ.prev = newNode; 6 if (pred == null) 7 first = newNode; 8 else 9 pred.next = newNode; 10 size++; 11 modCount++; 12 }

remove(index)源碼分析:同樣,這也是對引用的更改操作,方面多了!

1 E unlink(Node<E> x) { 2 // assert x != null; 3 final E element = x.item; 4 final Node<E> next = x.next; 5 final Node<E> prev = x.prev; 6 7 if (prev == null) { 8 first = next; 9 } else { 10 prev.next = next; 11 x.prev = null; 12 } 13 14 if (next == null) { 15 last = prev; 16 } else { 17 next.prev = prev; 18 x.next = null; 19 } 20 21 x.item = null; 22 size--; 23 modCount++; 24 return element; 25 }

get(index)源碼分析:利用指針挨個往后查找,直到找到位置為index的元素。當然了,找的時候也是要注意方法的,比如說利用二分查找。

1 Node<E> node(int index) { 2 // assert isElementIndex(index); 3 4 if (index < (size >> 1)) { 5 Node<E> x = first; 6 for (int i = 0; i < index; i++) 7 x = x.next; 8 return x; 9 } else { 10 Node<E> x = last; 11 for (int i = size - 1; i > index; i--) 12 x = x.prev; 13 return x; 14 } 15 }

Vector

-和ArrayList類似,可變數組實現的列表

????-Vector同步,適合在多線程下使用

????-原先不屬于JCF框架,屬于java最早的數據結構,性能較差

????-從JDK1.2開始,Vector被重寫,并納入JCF中

????-官方文檔建議在非同步的情況下,優先采用ArrayList

????其實vector類似于ArrayList,所以在一般情況下,我們能優先使用ArrayList,在同步的情況下,是可以考慮使用Vector

代碼例子:

1 public class VectorTest { 2 public static void main(String[] args) { 3 Vector<Integer> vs=new Vector<Integer>(); 4 vs.add(1); 5 vs.add(4); 6 vs.add(3); 7 vs.add(5); 8 vs.add(2); 9 vs.add(6); 10 vs.add(9); 11 System.out.println(vs); 12 System.out.println(vs.get(0)); 13 vs.remove(5); 14 System.out.println(vs); 15 /*Integer []a=new Integer[vs.size()]; 16 vs.toArray(a); 17 for(Integer m:a){ 18 System.out.print(m+" "); 19 }*/ 20 Vector <Integer> as=new Vector <Integer>(100000); 21 for(int i=0;i<1000000;i++){ 22 as.add(i); 23 } 24 traverseByIterator(as); 25 traverseByFor(as); 26 traverseByForEach(as); 27 traverseEm(as); 28 } 29 public static void traverseByIterator(Vector<Integer>al){ 30 System.out.println("---------迭代器遍歷-------------"); 31 long startTime=System.nanoTime();//開始時間 32 Iterator it=al.iterator(); 33 while(it.hasNext()){ 34 it.next(); 35 } 36 long endTime=System.nanoTime();//結束時間 37 System.out.println((endTime-startTime)+"納秒"); 38 } 39 public static void traverseByFor(Vector<Integer>al){ 40 System.out.println("---------索引遍歷-------------"); 41 long startTime=System.nanoTime();//開始時間 42 for(int i=0;i<al.size();i++) al.get(i); 43 long endTime=System.nanoTime();//結束時間 44 System.out.println((endTime-startTime)+"納秒"); 45 } 46 public static void traverseByForEach(Vector<Integer>al){ 47 System.out.println("---------Foreach遍歷-------------"); 48 long startTime=System.nanoTime();//開始時間 49 for(Integer temp:al){ 50 temp.intValue(); 51 } 52 long endTime=System.nanoTime();//結束時間 53 System.out.println((endTime-startTime)+"納秒"); 54 } 55 public static void traverseEm(Vector<Integer>al){ 56 System.out.println("---------Enumeration遍歷-------------"); 57 long startTime=System.nanoTime();//開始時間 58 for(Enumeration <Integer> ei=al.elements();ei.hasMoreElements();){ 59 ei.nextElement(); 60 } 61 long endTime=System.nanoTime();//結束時間 62 System.out.println((endTime-startTime)+"納秒"); 63 } 64 } 65 ---------迭代器遍歷------------- 66 28927404納秒 67 ---------索引遍歷------------- 68 32122768納秒 69 ---------Foreach遍歷------------- 70 25191768納秒 71 ---------Enumeration遍歷------------- 72 26901515納秒 73 可以看到Foreach遍歷要快于其他的遍歷方法。

add(index,value)源碼剖析:這個和ArrayList類似,需要進行元素的復制,所以很慢

1 public synchronized void insertElementAt(E obj, int index) { 2 modCount++; 3 if (index > elementCount) { 4 throw new ArrayIndexOutOfBoundsException(index 5 + " > " + elementCount); 6 } 7 ensureCapacityHelper(elementCount + 1); 8 System.arraycopy(elementData, index, elementData, index + 1, elementCount - index); 9 elementData[index] = obj; 10 elementCount++; 11 }

get(index)源碼剖析:可以看到,直接根據元素的下表返回數組元素。非常快!

1 public synchronized E get(int index) { 2 if (index >= elementCount) 3 throw new ArrayIndexOutOfBoundsException(index); 4 5 return elementData(index); 6 } 7 E elementData(int index) { 8 return (E) elementData[index]; 9 }

其實List這部分內容用的數學知識不是很多,但是set和Map確實是類似于數學模型的概念。期待后續Set,Map的學習。

個人微信公眾號

?

?

轉載于:https://www.cnblogs.com/zyxsblogs/p/10993847.html

總結

以上是生活随笔為你收集整理的数学知识巧学JCF(Java Collections framework)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。