一般來說課本上的數據結構包括數組、單鏈表、堆棧、樹、圖。我這里所指的數據結構,是一個怎么表示一個對象的問題,有時候,單單一個變量聲明不堪大用,比如int,String,double甚至一維數組、二維數組無法完全表達你要表達的東西,而定義一個類Class有太過麻煩,這時候,你可以考慮一下用Java中的Collections類。使用Collections類,必須在文件頭聲明import java.util.*;
一、動態、有序、可變大小的一維數組Vector與ArrayList
Collections類里面包括動態、有序、可變大小的一維數組Vector與ArrayList。
Vector與ArrayList,兩者唯一的差別是:vector自帶線程互斥,多個線程對其讀寫會拋出異常,而arraylist則允許多個線程讀寫,其他部分是一模一樣的,換句話說,如果是單線程在讀寫,使用Vector與ArrayList沒有任何區別,但現在編程基本都用ArrayList,使用Vector有點非主流了。
1、Vector的使用如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
public static void Vectortest() { // Vector<Double>表示這個vector只能存放double // Vector<String>表示這個vector只能存String // 雖然Vector<Object> vector=new Vector<Object>();等價于Vector vector=new // Vector();但是,eclipse中這樣寫會警告,表示你這個Vector不規范,╮(╯▽╰)╭ Vector<Object> vector = new Vector<Object>(); vector.add( 1.6 ); vector.add( 2.06 ); vector.add( 1 ); System.out.println( "單純的add表示從結尾加入元素:" + vector); System.out.println( "size()能求出vector的所含元素的個數:" + vector.size()); vector.remove( 1 ); System.out.println( "remove(1)表示刪去第1個元素,由于計數從0開始,也就是2.06這個元素:" + vector); vector.remove(vector.lastElement()); System.out.println( "刪去最后一個元素的vector為:" + vector); vector.add( 0 , 1.8888 ); System.out.println( "在第0個位置加入1.8888這個元素:" + vector); vector.set( 0 , "a" ); System.out.println( "把第0個位置這個元素改為a:" + vector); } |
這段方法如果在主函數調用:
1
2
3
|
System.out.println( "======Vector數據結構的測試開始======" ); Vectortest(); System.out.println( "======Vector數據結構的測試結束======" ); |
運行結果如下:
======Vector數據結構的測試開始======
單純的add表示從結尾加入元素:[1.6, 2.06, 1]
size()能求出vector的所含元素的個數:3
remove(1)表示刪去第1個元素,由于計數從0開始,也就是2.06這個元素:[1.6, 1]
刪去最后一個元素的vector為:[1.6]
在第0個位置加入1.8888這個元素:[1.8888, 1.6]
把第0個位置這個元素改為a:[a, 1.6]
======Vector數據結構的測試結束======
2、ArrayList
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
public static void ArrayListtest() { ArrayList<Double> arraylist = new ArrayList<Double>(); arraylist.add( 1.0 ); arraylist.add( 4.0 ); arraylist.add( 5.0 ); arraylist.add( 2.3 ); System.out.println( "單純的add表示從結尾加入元素:" + arraylist); System.out.println( "size()能求出所含元素的個數:" + arraylist.size()); arraylist.remove( 1 ); System.out.println( "remove(1)表示刪去第1個元素,由于計數從0開始,也就是4這個元素:" + arraylist); arraylist.remove(arraylist.size() - 1 ); System.out.println( "刪去最后一個元素的arraylist為:" + arraylist); arraylist.add( 0 , 1.8888 ); System.out.println( "在第0個位置加入1.8888這個元素:" + arraylist); arraylist.set( 0 , 9.0 ); System.out.println( "把第0個位置這個元素改為a:" + arraylist); Collections.sort(arraylist); System.out.println( "如果arraylist不是抽象類型,則支持排序" + arraylist); } |
這里可以看到ArrayList刪除最后一個元素的方式與Vector有所不同,主要是ArrayList沒有lastElement()這個方法來取出最后一個元素remove()掉,只能用arraylist.size() - 1來確定最后一個元素的位置。如果在主函數這樣調用這段方法:
1
2
3
|
System.out.println( "======ArrayList數據結構的測試開始======" ); ArrayListtest(); System.out.println( "======ArrayList數據結構的測試結束======" ); |
則得到如下的運行結果:
======ArrayList數據結構的測試開始======
單純的add表示從結尾加入元素:[1.0, 4.0, 5.0, 2.3]
size()能求出所含元素的個數:4
remove(1)表示刪去第1個元素,由于計數從0開始,也就是4這個元素:[1.0, 5.0, 2.3]
刪去最后一個元素的arraylist為:[1.0, 5.0]
在第0個位置加入1.8888這個元素:[1.8888, 1.0, 5.0]
把第0個位置這個元素改為a:[9.0, 1.0, 5.0]
如果arraylist不是抽象類型,則支持排序[1.0, 5.0, 9.0]
======ArrayList數據結構的測試結束======
從上面的兩個例子,可以看到Vector與ArrayList比一個普通的數組,也就是課本上所教的一維數組int array[] = { 8, 7, 100, 88, 6, 4, 5, 33, 7 };強大很多,可以在任意位置插入元素,也可以不用遍歷數組就能夠用一個方法刪除指定位置的元素,當然為你考試你還是要知道這個數組是怎么遍歷的。其實,ArrayList與普通的一維數組完全可以實現互轉,而且利用ArrayList還能夠直接對array進行排序,而不用再對array寫一個冒泡排序之類的,直接用Collections.sort();就能夠排序數組,然后再用Collections.reverse();就能實現逆排序,當然還是那句,為你考試你還是要知道這個數組是怎么排序的。
比如如下的方法,實現了對一維數組int array[] = { 8, 7, 100, 88, 6, 4, 5, 33, 7 };的排序與逆排序,先把數組轉化成ArrayList再用Collections.sort();與Collections.reverse();排序,最后再把ArrayList內容轉化回一維數組:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
public static void arrayListSort() { int array[] = { 8 , 7 , 100 , 88 , 6 , 4 , 5 , 33 , 7 }; ArrayList<Integer> arraylist = new ArrayList<Integer>(); for ( int i = 0 ; i < array.length; i++) System.out.print(array[i] + "," ); for ( int i = 0 ; i < array.length; i++) arraylist.add(array[i]); Collections.sort(arraylist); for ( int i = 0 ; i < array.length; i++) array[i] = arraylist.get(i); System.out.print( "排序后的數組:" ); for ( int i = 0 ; i < array.length; i++) System.out.print(array[i] + "," ); Collections.reverse(arraylist); for ( int i = 0 ; i < array.length; i++) array[i] = arraylist.get(i); System.out.print( "逆排序后的數組:" ); for ( int i = 0 ; i < array.length; i++) System.out.print(array[i] + "," ); //排序之后把arraylist銷毀 arraylist = null ; //這句是建議Java馬上回收垃圾,當然這句有沒有都行,Java在運行的過程中會自動清除垃圾的 System.gc(); } |
在主函數中這樣調用方法:
1
2
3
|
System.out.println( "======Java數組排序開始======" ); arrayListSort(); System.out.println( "======Java數組排序結束======" ); |
就能夠得到如下的運行結果:
======Java數組排序開始======
8,7,100,88,6,4,5,33,7,排序后的數組:4,5,6,7,7,8,33,88,100,逆排序后的數組:100,88,33,8,7,7,6,5,4,
======Java數組排序結束======
另外,之前說的《Java中List的使用方法簡單介紹》(點擊打開鏈接)也是同樣的道理
二、集合HashSet
另外,還有集合HashSet,HashSet與數學上的集合概念一模一樣。由一個或多個元素所構成的叫做集合。HashSet具有:
1.確定性,集合中的元素必須是確定的,這個是廢話,必須確定,難道我還可以在里面放一個不確定的東西進去嗎?
2.互異性,集合中的元素互不相同。例如:集合A={1,a},則a不能等于1,也就是如果你把兩個1放進HashSet會自動變為一個1
3.無序性,集合中的元素沒有先后之分。因此HashSet也不得進行排序操作
例如如下的一段方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
public static void HashSettest() { HashSet<Object> hashset = new HashSet<Object>(); hashset.add( 1 ); hashset.add( 1 ); hashset.add( 5 ); hashset.add( 2.3 ); System.out.println( "單純的add表示從結尾加入元素:" + hashset); System.out.println( "size()能求出所含元素的個數:" + hashset.size()); hashset.remove( 1 ); System.out.println( "remove(1)表示刪去'1'這個元素:" + hashset); hashset.remove( "asd" ); System.out.println( "如果沒有'asd'這個元素則remove什么都不做:" + hashset); hashset.add( 1.8888 ); System.out.println( "加入1.8888這個元素:" + hashset); } |
在主函數中,調用這個方法:
1
2
3
|
System.out.println( "======HashSet數據結構的測試開始======" ); HashSettest(); System.out.println( "======HashSet數據結構的測試結束======" ); |
結果如下:
======HashSet數據結構的測試開始======
單純的add表示從結尾加入元素:[1, 5, 2.3]
size()能求出所含元素的個數:3
remove(1)表示刪去'1'這個元素:[5, 2.3]
如果沒有'asd'這個元素則remove什么都不做:[5, 2.3]
加入1.8888這個元素:[5, 1.8888, 2.3]
======HashSet數據結構的測試結束======
HashSet有add()方法與remove()方法,add()所加的元素沒有順序,每次用System.out.println()打印的結果可能順序不一樣,也不能向上面Vector與ArrayList一樣,只要所存的元素不是Object,就能使用Collections.sort(arraylist);來排序
三、二元組HashMap
這里的使用方法和上面的數據基本相同,也很簡單,就是put方法來對象進去map,而get能夠取走map中的對象,但是試圖把二元組HashMap用成三元組是錯誤的,如果一個對象中含有元素過多,那你應該考慮用類。而不是還在迷戀Java中介乎于普通變量與Class類之間的Collections類。
比如如下方法就展示了試圖把HashMap改成三元組的錯誤操作:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
public static void Maptest(){ System.out.println( "======Map錯誤的使用開始======" ); HashMap<String,String> map= new HashMap<String, String>(); HashMap<String,HashMap<String, String>> bigmap= new HashMap<String, HashMap<String, String>>(); map.put( "key1" , "1" ); map.put( "key2" , "2" ); bigmap.put( "test1" ,map); map.clear(); map.put( "key1" , "3" ); map.put( "key2" , "4" ); bigmap.put( "test2" ,map); System.out.println(bigmap); System.out.println(bigmap.get( "test1" ).get( "key1" )); System.out.println(bigmap.get( "test1" ).get( "key2" )); System.out.println(bigmap.get( "test2" ).get( "key1" )); System.out.println(bigmap.get( "test2" ).get( "key2" )); System.out.println( "======Map錯誤的使用結束======" ); System.out.println( "======Map正確的使用開始======" ); map.clear(); bigmap= null ; map.put( "key1" , "1" ); map.put( "key2" , "2" ); map.put( "key3" , "3" ); System.out.println(map); System.out.println( "======Map正確的使用結束======" ); } |
在主函數調用這段代碼,得到下面的運行結果:
======Map數據結構的測試開始======
======Map錯誤的使用開始======
{test1={key2=4, key1=3}, test2={key2=4, key1=3}}
3
4
3
4
======Map錯誤的使用結束======
======Map正確的使用開始======
{key3=3, key2=2, key1=1}
======Map正確的使用結束======
======Map數據結構的測試結束======
這段程序本來用意是很明顯,試圖構造出一個{test1,key1,1},{test1,key2,2},{test2,key3,3},{test2,key4,4}
然而,每個bigmap中還是存得都是那個map,你一旦把map清空,原來test1中的那個map也同樣被清空, 有人試圖創造多個map1,map2,...那你還不如用一個簡單的類,看起來更加明確,而且類中以后還能寫方法,被繼承
四、備注
在創造一個新的Vector,Arraylist好,HashSet也好,HashMap也好,完全可以寫成:
Collection<String> a= new ArrayList<String>();
List<String> a= new Vector<String>();之類
因為繼承于Collection接口的有ArrayList、Vector、Linkedlist、HashSet、TreeSet,繼承于MAP接口的有HashMap、Hashtable,這是Java中類的繼承、多態、封裝之類的問題,當然為了你的同伴看得更加清晰,這里就不要玩什么花哨命名了,寫一個清楚的ArrayList<Integer> arraylist = new ArrayList<Integer>();沒人敢說你不懂Java中的類。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。