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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java基础系列:集合总结(6)

發(fā)布時(shí)間:2025/3/20 编程问答 14 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java基础系列:集合总结(6) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

排序和搜索

數(shù)組

Arrays類為所有基本數(shù)據(jù)類型的數(shù)組提供了一個(gè)過載的 sort()和 binarySearch(),它們亦可用于 String 和Object。

public class Array1 {static Random r = new Random();static String ssource = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"+ "abcdefghijklmnopqrstuvwxyz";static char[] src = ssource.toCharArray();// Create a random Stringpublic static String randString(int length) {char[] buf = new char[length];int rnd;for (int i = 0; i < length; i++) {rnd = Math.abs(r.nextInt()) % src.length;buf[i] = src[rnd];}return new String(buf);}// Create a random array of Strings:public static String[] randStrings(int length, int size) {String[] s = new String[size];for (int i = 0; i < size; i++)s[i] = randString(length);return s;}public static void print(byte[] b) {for (int i = 0; i < b.length; i++)System.out.print(b[i] + " ");System.out.println();}public static void print(String[] s) {for (int i = 0; i < s.length; i++)System.out.print(s[i] + " ");System.out.println();}public static void main(String[] args) {byte[] b = new byte[15];r.nextBytes(b); // Fill with random bytesprint(b);Arrays.sort(b);print(b);int loc = Arrays.binarySearch(b, b[10]);System.out.println("Location of " + b[10] + " = " + loc);// Test String sort & search:String[] s = randStrings(4, 10);print(s);Arrays.sort(s);print(s);loc = Arrays.binarySearch(s, s[4]);System.out.println("Location of " + s[4] + " = " + loc);} }

在 main()中, Random.nextBytes()
用隨機(jī)選擇的字節(jié)填充數(shù)組自變量(沒有對(duì)應(yīng)的Random 方法用于創(chuàng)建其他基本數(shù)據(jù)類型的數(shù)組)。獲得一個(gè)數(shù)組后,便可發(fā)現(xiàn)為了執(zhí)行 sort()或者 binarySearch(),只需發(fā)出一次方法調(diào)用即可。與 binarySearch()有關(guān)的還有一個(gè)重要的警告:若在執(zhí)行一次 binarySearch()之前不調(diào)用 sort(),便會(huì)發(fā)生不可預(yù)測(cè)的行為,其中甚至包括無限循環(huán)。
對(duì) String 的排序以及搜索是相似的,但在運(yùn)行程序的時(shí)候,我們會(huì)注意到一個(gè)有趣的現(xiàn)象:排序遵守的是字典順序,亦即大寫字母在字符集中位于小寫字母的前面。因此,所有大寫字母都位于列表的最前面,后面再跟上小寫字母—— Z 居然位于 a 的前面。似乎連電話簿也是這樣排序的。
- 可比較與比較器
若想對(duì)一個(gè) Object 數(shù)組進(jìn)行排序,那么必須解決一個(gè)問題。根據(jù)什么來判定兩個(gè) Object 的順序呢?不幸的是,最初的 Java 設(shè)計(jì)者并不認(rèn)為這是一個(gè)重要的問題,否則就已經(jīng)在根類 Object 里定義它了。這樣造成的一個(gè)后果便是:必須從外部進(jìn)行 Object 的排序,而且新的集合庫提供了實(shí)現(xiàn)這一操作的標(biāo)準(zhǔn)方式(最理想的是在 Object 里定義它)。
針對(duì) Object 數(shù)組(以及 String,它當(dāng)然屬于 Object 的一種),可使用一個(gè) sort(),并令其接納另一個(gè)參數(shù):實(shí)現(xiàn)了 Comparator 接口(即“比較器”接口,新集合庫的一部分)的一個(gè)對(duì)象,并用它的單個(gè)compare()方法進(jìn)行比較。這個(gè)方法將兩個(gè)準(zhǔn)備比較的對(duì)象作為自己的參數(shù)使用—— 若第一個(gè)參數(shù)小于第二個(gè),返回一個(gè)負(fù)整數(shù);若相等,返回零;若第一個(gè)參數(shù)大于第二個(gè),則返回正整數(shù)。基于這一規(guī)則,上述例子的 String 部分便可重新寫過,令其進(jìn)行真正按字母順序的排序:
通過造型為 String, compare()方法會(huì)進(jìn)行“暗示”性的測(cè)試,保證自己操作的只能是 String 對(duì)象—— 運(yùn)期系統(tǒng)會(huì)捕獲任何差錯(cuò)。將兩個(gè)字串都強(qiáng)迫換成小寫形式后, String.compareTo()方法會(huì)產(chǎn)生預(yù)期的結(jié)果若用自己的 Comparator 來進(jìn)行一次 sort(),那么在使用 binarySearch()時(shí)必須使用那個(gè)相同的Comparator。
Arrays 類提供了另一個(gè) sort()方法,它會(huì)采用單個(gè)自變量:一個(gè) Object 數(shù)組,但沒有 Comparator。這個(gè)
sort()方法也必須用同樣的方式來比較兩個(gè) Object。通過實(shí)現(xiàn) Comparable 接口,它采用了賦予一個(gè)類的“自然比較方法”。 這個(gè)接口含有單獨(dú)一個(gè)方法—— compareTo(),能分別根據(jù)它小于、等于或者大于自變量而返回負(fù)數(shù)、零或者正數(shù),從而實(shí)現(xiàn)對(duì)象的比較。

public class CompClass implements Comparable {private int i;public CompClass(int ii) {i = ii;}public int compareTo(Object o) {// Implicitly tests for correct type:258int argi = ((CompClass) o).i;if (i == argi)return 0;if (i < argi)return -1;return 1;}public static void print(Object[] a) {for (int i = 0; i < a.length; i++)System.out.print(a[i] + " ");System.out.println();}public String toString() {return i + "";}public static void main(String[] args) {CompClass[] a = new CompClass[20];for (int i = 0; i < a.length; i++)a[i] = new CompClass((int) (Math.random() * 100));print(a);Arrays.sort(a);print(a);int loc = Arrays.binarySearch(a, a[3]);System.out.println("Location of " + a[3] + " = " + loc);} }
  • 列表
    可用與數(shù)組相同的形式排序和搜索一個(gè)列表( List)。用于排序和搜索列表的靜態(tài)方法包含在類Collections 中,但它們擁有與 Arrays 中差不多的簽名: sort(List)用于對(duì)一個(gè)實(shí)現(xiàn)了 Comparable 的對(duì)象列表進(jìn)行排序; binarySearch(List,Object)用于查找列表中的某個(gè)對(duì)象; sort(List,Comparator)利用一個(gè)“比較器”對(duì)一個(gè)列表進(jìn)行排序;而binarySearch(List,Object,Comparator)則用于查找那個(gè)列表中的一個(gè)對(duì)象
public class ListSort {public static void main(String[] args) {final int SZ = 20;// Using "natural comparison method":List a = new ArrayList();for(int i = 0; i < SZ; i++)a.add(new CompClass((int)(Math.random() *100)));Collection1.print(a);Collections.sort(a);Collection1.print(a);Object find = a.get(SZ/2);259int loc = Collections.binarySearch(a, find);System.out.println("Location of " + find +" = " + loc);// Using a Comparator:List b = new ArrayList();for(int i = 0; i < SZ; i++)b.add(Array1.randString(4));Collection1.print(b);AlphaComp ac = new AlphaComp();Collections.sort(b, ac);Collection1.print(b);find = b.get(SZ/2);// Must use the Comparator to search, also:loc = Collections.binarySearch(b, find, ac);System.out.println("Location of " + find +" = " + loc);} }

這些方法的用法與在 Arrays 中的用法是完全一致的,只是用一個(gè)列表代替了數(shù)組。
TreeMap 也必須根據(jù) Comparable 或者 Comparator 對(duì)自己的對(duì)象進(jìn)行排序
Collections 類中的實(shí)用工具:
enumeration(Collection) 為自變量產(chǎn)生原始風(fēng)格的 Enumeration(枚舉)
max(Collection), min(Collection) 在自變量中用集合內(nèi)對(duì)象的自然比較方法產(chǎn)生最大或最小元素
max(Collection,Comparator), min(Collection,Comparator) 在集合內(nèi)用比較器產(chǎn)生最大或最小元素
nCopies(int n, Object o) 返回長度為 n 的一個(gè)不可變列表,它的所有句柄均指向 o
subList(List,int min,int max) 返回由指定參數(shù)列表后推得到的一個(gè)新列表。可將這個(gè)列表想象成一個(gè)
“窗口”,它自索引為 min 的地方開始,正好結(jié)束于 max 的前面
注意 min()和 max()都是隨同 Collection 對(duì)象工作的,而非隨同 List,所以不必?fù)?dān)心 Collection 是否需要排序(就象早先指出的那樣,在執(zhí)行一次 binarySearch()—— 即二進(jìn)制搜索—— 之前,必須對(duì)一個(gè) List 或者一個(gè)數(shù)組執(zhí)行 sort())

1. 使 Collection 或 Map 不可修改

通常,創(chuàng)建 Collection 或 Map 的一個(gè)“只讀”版本顯得更有利一些。 Collections 類允許我們達(dá)到這個(gè)目標(biāo),方法是將原始容器傳遞進(jìn)入一個(gè)方法,并令其傳回一個(gè)只讀版本。這個(gè)方法共有四種變化形式,分別用于 Collection(如果不想把集合當(dāng)作一種更特殊的類型對(duì)待)、 List、 Set 以及 Map。

public class ReadOnly {public static void main(String[] args) {Collection c = new ArrayList();Collection1.fill(c); // Insert useful datac = Collections.unmodifiableCollection(c);Collection1.print(c); // Reading is OK// ! c.add("one"); // Can't change itList a = new ArrayList();Collection1.fill(a);a = Collections.unmodifiableList(a);ListIterator lit = a.listIterator();System.out.println(lit.next()); // Reading OK// ! lit.add("one"); // Can't change itSet s = new HashSet();Collection1.fill(s);s = Collections.unmodifiableSet(s);Collection1.print(s); // Reading OK// ! s.add("one"); // Can't change itMap m = new HashMap();Map1.fill(m, Map1.testData1);m = Collections.unmodifiableMap(m);Map1.print(m); // Reading OK// ! m.put("Ralph", "Howdy!");} }

對(duì)于每種情況,在將其正式變?yōu)橹蛔x以前,都必須用有有效的數(shù)據(jù)填充容器。一旦載入成功,最佳的做法就是用“不可修改”調(diào)用產(chǎn)生的句柄替換現(xiàn)有的句柄。這樣做可有效避免將其變成不可修改后不慎改變其中的內(nèi)容。
在另一方面,該工具也允許我們?cè)谝粋€(gè)類中將能夠修改的容器保持為private 狀態(tài),并可從一個(gè)方法調(diào)用中返回指向那個(gè)容器的一個(gè)只讀句柄。這樣一來,雖然我們可在類里修改它,但其他任何人都只能讀。
為特定類型調(diào)用“不可修改”的方法不會(huì)造成編譯期間的檢查,但一旦發(fā)生任何變化,對(duì)修改特定容器的方法的調(diào)用便會(huì)產(chǎn)生一個(gè) UnsupportedOperationException 違例。

2.Collection 或 Map 的同步

在這兒,大家只需注意到 Collections 類提供了對(duì)整個(gè)容器進(jìn)行自動(dòng)同步的一種途徑。它的語法與“不可修改”的方法是類似的:

public class Synchronization {public static void main(String[] args) {Collection c = Collections.synchronizedCollection(new ArrayList());List list = Collections.synchronizedList(new ArrayList());Set s = Collections.synchronizedSet(new HashSet());Map m = Collections.synchronizedMap(new HashMap());} }

總結(jié)

(1) 數(shù)組包含了對(duì)象的數(shù)字化索引。它容納的是一種已知類型的對(duì)象,所以在查找一個(gè)對(duì)象時(shí),不必對(duì)結(jié)果進(jìn)行造型處理。數(shù)組可以是多維的,而且能夠容納基本數(shù)據(jù)類型。但是,一旦把它創(chuàng)建好以后,大小便不能變化了。
(2) Vector(矢量)也包含了對(duì)象的數(shù)字索引—— 可將數(shù)組和 Vector 想象成隨機(jī)訪問集合。當(dāng)我們加入更多的元素時(shí), Vector 能夠自動(dòng)改變自身的大小。但 Vector 只能容納對(duì)象的句柄,所以它不可包含基本數(shù)據(jù)類型;而且將一個(gè)對(duì)象句柄從集合中取出來的時(shí)候,必須對(duì)結(jié)果進(jìn)行造型處理。
(3) Hashtable(散列表)屬于 Dictionary(字典)的一種類型,是一種將對(duì)象(而不是數(shù)字)同其他對(duì)象關(guān)聯(lián)到一起的方式。散列表也支持對(duì)對(duì)象的隨機(jī)訪問,事實(shí)上,它的整個(gè)設(shè)計(jì)方案都在突出訪問的“高速度”。
(4) Stack(堆棧)是一種“后入先出”( LIFO)的隊(duì)列
對(duì)于 Hashtable,可將任何東西置入其中,并以非常快的速度檢索;對(duì)于 Enumeration(枚舉),可遍歷一個(gè)序列,并對(duì)其中的每個(gè)元素都采取一個(gè)特定的操作。那是一種功能足夠強(qiáng)勁的工具。
但 Hashtable 沒有“順序”的概念。 Vector 和數(shù)組為我們提供了一種線性順序,但若要把一個(gè)元素插入它們?nèi)魏我粋€(gè)的中部,一般都要付出“慘重”的代價(jià)。除此以外,隊(duì)列、拆散隊(duì)列、優(yōu)先級(jí)隊(duì)列以及樹都涉及到元素的“排序” —— 并非僅僅將它們置入,以便以后能按線性順序查找或移動(dòng)它們。

總結(jié)

以上是生活随笔為你收集整理的java基础系列:集合总结(6)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。