由於工作原因,已經有兩禮拜沒有更新博客了,好不容易完成了工作項目,終於又可以在博客園上愉快的玩耍了。
嗯,今天下午梳理了一下關於java枚舉的筆記,比較長,不過還是覺得挺厚實的,哈哈,有出入的地方,歡迎朋友們指出來,一起學習,共同進步!!
一、枚舉簡介:
為什么要用枚舉:
枚舉是Java1.5出來之后新增的類型,它可以用來定義一組取值范圍固定的的變量。
在枚舉沒有出來之前,要定義這樣的變量,往往是通過定義一個接口,將不同的變量
使用不同的整數賦值。但是這樣的卻有着很明顯的缺點:
1.不能保證其定義數值的合法性;
2.無法根據數值大小獲取其含義。
但是通過枚舉這些問題將不再是問題。
--支持知識共享,轉載請標注地址"http://www.cnblogs.com/XHJT/p/3945401.html "——和佑博客園,謝謝~~--
枚舉特性:
1.Enum類是枚舉的一個封裝類,,是所有枚舉類型的超類,它是一個沒有抽象方法的抽象類。
2.通過關鍵字"enum"可以定義枚舉類型;
3.Enum類中定義了很多常用的方法:如元素間的比較,獲取元素名稱,獲取元素定義的次序等:
a.compareTo(E o) : 比較枚舉元素的順序
b.equals(Object obj) : 判斷枚舉元素是否相同
c. name() : 獲取元素定義時的名稱
d.ordinal() : 獲取枚舉元素被定義時的順序,從0開始計算
注:對於枚舉可以使用"=="來比較兩個枚舉元素相同與否,由於他們已經自動了equals()和hashCode()兩個方法,
故這兩個方法不需要重寫。
枚舉的簡單運用之創建和調用枚舉:
1.枚舉類的定義:
public enum Demo{
ENUMTYPEA,ENUMTYPEB,ENUMTYPEC;
}
2.在枚舉類中,所有的屬性以大寫的形式存在,屬性之間以逗號隔開,屬性的值以括號String類型存在;
3.若是枚舉屬性有值strName,則需要定義這個strName,並且定義枚舉類的有參構造方法,即必須要要先
定義枚舉類型description才能定義構造方法Demo(String description);
public enum Demo{
ENUMTYPEA(strName),//枚舉類型A,strName==" 枚舉類型屬性的值";
ENUMTYPEB(strName),//枚舉類型B
ENUMTYPEC(strName);//枚舉類型C
private String description;
private Demo(String description){
this.descrition = descrition;
}
public String getDescription(){
return description;
}
}
4.枚舉類不能被繼承,但可看作普通類,可重寫方法,可有main方法。
5.枚舉類的構造方法可以用public和protected修飾,但只能用來創建枚舉對象,不能創建枚舉類的實例
代碼實例:
無參枚舉類:
package com.xhj.Enum; /** * 無參枚舉 * * @author XIEHEJUN * */ public enum Color { BLUE, YELLOW, RED, GREEN, WHITE, BRACK, PURPLE }
有參枚舉類:
package com.xhj.Enum; /** * 有參枚舉 * * @author XIEHEJUN * */ public enum ColorValues { BLUE("藍色"), YELLOW("黃色"), RED("紅色"), GREEN("綠色"), WHITE("白色"), BRACK("黑色"), PURPLE( "紫色"); private String description; private ColorValues(String description) { this.description = description; } public String getDescription() { return description; } }
枚舉測試類:
package com.xhj.Enum; /** * 對枚舉封裝類方法的簡單運用 * * @author XIEHEJUN * */ public class Test { /** * 調用無參枚舉 */ public static void printColor() { for (Color color : Color.values()) { System.out.println("第" + (color.ordinal() + 1) + "個枚舉是:" + color.name()); System.out .println("此枚舉和枚舉BLUE比較的值為:" + color.compareTo(color.BLUE)); System.out.println("用'equals()方法'判斷此枚舉是否和枚舉BLUE相等為:" + color.equals(color.BLUE)); System.out.println("用'== '的形式判斷此枚舉是否和枚舉BLUE相等為:" + (color == color.BLUE)); System.out.println(color.getDeclaringClass()); System.out .println("========================================================"); } } /** * 調用有參枚舉 */ public static void printColorValues() { for (ColorValues colorValues : ColorValues.values()) { System.out.println("第" + (colorValues.ordinal() + 1) + "個枚舉是:" + colorValues.name()); System.out.println("此枚舉的值為:" + colorValues.getDescription()); System.out.println("此枚舉和枚舉BLUE比較的值為:" + colorValues.compareTo(colorValues.BLUE)); System.out.println("用'equals()方法'判斷此枚舉是否和枚舉BLUE相等為:" + colorValues.equals(colorValues.BLUE)); System.out.println("用'== '的形式判斷此枚舉是否和枚舉BLUE相等為:" + (colorValues == colorValues.BLUE)); System.out.println(colorValues.getDeclaringClass()); System.out .println("========================================================"); } } public static void main(String[] args) { Test Test.printColor(); System.out .println("***************************************************************\n" +"***************************************************************"); Test.printColorValues(); } }
枚舉的簡單運用之switch調用枚舉:
我們知道在java7(加上了switch可以調用String類型的特性)沒有出來之前switch只能調用整數類型變量。
我想很多人可能會說,這個結論不對,因為他還可以調用枚舉類型。
是的,沒有錯,switch確實可以調用枚舉類型,但是她能調用的必要前提是調用的類型必須是整數。這個怎么理解呢?
其實,事實上是因為枚舉類會自動的為它的每一個元素生成一個整數的順序編號(可以通過ordinal()方法獲知其編號),
所以當我們向switch傳入枚舉類型時,事實上,傳進去的是一個整數--元素的順序編號。
代碼實例:
package com.xhj.Enum; /** * switch枚舉類型的調用 * * @author XIEHEJUN * */ public enum UseSwitch { LILEI, LILY, SHITOU; /** * 獲取每一個USER的性別 * * @param user * @return */ public static String getGrend(UseSwitch user) { switch (user) { case LILEI: return "我是一名男孩"; case LILY: return "我是一名女孩"; default: return "咦?我是誰呢?"; } } public static void main(String[] args) { for (UseSwitch user : UseSwitch.values()) { System.out.println(user + ":" + user.getGrend(user)); } } }
注:在switch語句中,若是有return返回值,則必須要有default語句:
二、枚舉的高效運用:
枚舉的高效運用之枚舉集合:
Set回顧:
Set是Java集合類中一個很重要的子類,它用來存儲不能重復的對象。
枚舉和Set對比:
1.枚舉也和Set一樣要求每一個枚舉元素都必須各不相同;
2.Set可以隨意對數據進行增刪操作,枚舉不能。
EnumSet:
1.枚舉集合,和Set集合一樣,保證每一個元素的唯一性,不可重復性;
2.當創建EnumSet對象時,需要顯式或隱士指明元素的枚舉類型;
3.此對象中的元素僅能取自同一枚舉類
4.在EnumSet內部以"位向量"的形式表示,這種結構緊湊而高效,使得類的時間、控件性能非常優越。
5.常用方法:
allOf(Class<E> elementType): 創建一個EnumSet,它包含了elementType 中所有枚舉元素
complementOf(EnumSet<E> s): 創建一個EnumSet,其中的元素是s的補集
noneOf(Class<E> elementType): 創建一個EnumSet,其中的元素的類型是elementType,但是沒有元素
range(E from, E to): 創建一個EnumSet,其中的元素在from和to之間,包括端點
add(E e): 增加一個元素e
remove(Object o): 刪除一個元素o
addAll(Collection<? extends E>): 增加一個集合元素c
removeAll(Collection<?> c): 刪除一集合元素c
注:不能在EnumSet中增加null元素,否則將會拋出空指針異常
代碼實例:
package com.xhj.Enum; import java.util.EnumSet; /** * EnumSet的運用 * * @author XIEHEJUN * */ public class EnumSetDemo { /** * 獲取元素信息並打印輸出 * * @param enumSet */ public static void getElement(EnumSet<ColorValues> enumSet) { StringBuffer strName = new StringBuffer(); for (int j = 0; j < enumSet.size(); j++) { System.out.print("\t" + enumSet.toArray()[j]); for (ColorValues colorValues2 : enumSet) { strName.append("\t" + colorValues2.getDescription() + "\n"); } System.out.println(strName.toString().split("\n")[j]); } } /** * EnumSet方法的具體使用實例 */ public static void getEnumSet() { EnumSet<ColorValues> enumSet1 = EnumSet.allOf(ColorValues.class); System.out.println("enumSet1枚舉集合中元素有" + enumSet1.size() + "個"); System.out.println("分別是:"); getElement(enumSet1); System.out .println("=====================添加元素============================"); EnumSet<ColorValues> enumSet2 = EnumSet.noneOf(ColorValues.class); System.out.println("\n此時枚舉集合enumSet2中元素有" + enumSet2.size() + "個"); System.out.println("\n向枚舉集合enumSet2添加一個元素" + ColorValues.BLUE); enumSet2.add(ColorValues.BLUE); System.out.println("此時枚舉集合enumSet2中元素個數有:" + enumSet2.size()); getElement(enumSet2); System.out.println("\n向枚舉集合enumSet2添加一個元素" + ColorValues.RED); enumSet2.add(ColorValues.RED); System.out.println("此時枚舉集合enumSet2中元素個數有:" + enumSet2.size()); getElement(enumSet2); System.out.println("\n向枚舉集合enumSet2添加一個元素" + ColorValues.GREEN); enumSet2.add(ColorValues.GREEN); System.out.println("此時枚舉集合enumSet2中元素個數有:" + enumSet2.size()); getElement(enumSet2); System.out.println("\n向枚舉集合enumSet2添加ColorValues的補集enumSet3"); EnumSet<ColorValues> enumSet3 = EnumSet.complementOf(enumSet2); getElement(enumSet3); enumSet2.addAll(enumSet3); System.out.println("\n此時枚舉集合enumSet2中元素個數有:" + enumSet2.size()); getElement(enumSet2); System.out .println("=====================刪除元素============================"); System.out.println("\n枚舉集合enumSet2刪除一個元素" + ColorValues.GREEN); enumSet2.remove(ColorValues.GREEN); System.out.println("此時枚舉集合enumSet2中元素個數有:" + enumSet2.size()); getElement(enumSet2); System.out.println("\n枚舉集合enumSet2刪除一個固定范圍內的元素"); enumSet2.removeAll(enumSet2 .range(ColorValues.YELLOW, ColorValues.WHITE)); System.out.println("此時枚舉集合enumSet2中元素個數有:" + enumSet2.size()); getElement(enumSet2); System.out.println("\n枚舉集合enumSet2刪除一個枚舉集合enumSet3,這個集合的元素個數有:" + enumSet3.size()); enumSet2.removeAll(enumSet3); System.out.println("此時枚舉集合enumSet2中元素個數有:" + enumSet2.size()); getElement(enumSet2); System.out .println("=====================清除所有元素============================"); enumSet2.clear(); System.out.println("此時枚舉集合enumSet2中元素個數有:" + enumSet2.size()); } public static void main(String[] args) { EnumSetDemo.getEnumSet(); } }
枚舉的高效運用之枚舉映射:
1.對於枚舉集合來說,Java除了提供EnumSet外,還提供了另外一個集合類EnumMap
2.Map是Java集合類的子類,主要是通過鍵值對來保存對象,要求其鍵必須是唯一的;
3.在枚舉類型中,枚舉元素也是要求唯一的,固可作為Map的鍵。
4.EnumMap類是Java專門為枚舉類型提供的Map實現類。
5.和EnumSet類一樣,當創建EnumMap類型時,要顯式或者隱式指明其元素的枚舉類型,且只能取自統一枚舉類
6.在EunmMap內部,用數組表示
7.常用方法:
clear(): 刪除所有映射關系
containKey(Object key): 若包含此key,則返回true,否則返回false
containsValue(Object value): 若包含此value,則返回true,否者返回false
put(K key,V value): 往EnumMap中存入鍵值對
get(Object key): 獲取鍵為key對應的value值
size(): 查看EnumMap中鍵值對的個數
remove(Object key): 刪除鍵為key相對應的value值
注:在EunmMap中,不可存入null,否則將拋出空指針異常
代碼實例:
package com.xhj.Enum; import java.util.EnumMap; /** * EnumMap的運用 * * @author XIEHEJUN * */ public class EnumMapDemo { /** * EnumMap的具體運用 */ public static void getEnumMap() { EnumMap<ColorValues, String> enumMap1 = new EnumMap<ColorValues, String>( ColorValues.class); String[] Weeks = { "星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期天" }; System.out .println("==========================添加枚舉鍵值對================================"); enumMap1.put(ColorValues.BLUE, ColorValues.BLUE.getDescription() + Weeks[ColorValues.BLUE.ordinal()]); System.out.println("key=0時enumMap1的元素有 " + enumMap1); System.out.println(" 此時鍵值對個數為: " + enumMap1.size() + "\n"); enumMap1.put(ColorValues.BRACK, ColorValues.BRACK.getDescription() + Weeks[ColorValues.BRACK.ordinal()]); System.out.println("key=1時enumMap1的元素有 " + enumMap1); System.out.println(" 此時鍵值對個數為: " + enumMap1.size() + "\n"); enumMap1.put(ColorValues.GREEN, ColorValues.GREEN.getDescription() + Weeks[ColorValues.GREEN.ordinal()]); System.out.println("key=2時enumMap1的元素有 " + enumMap1); System.out.println(" 此時鍵值對個數為: " + enumMap1.size() + "\n"); enumMap1.put(ColorValues.PURPLE, ColorValues.PURPLE.getDescription() + Weeks[ColorValues.PURPLE.ordinal()]); System.out.println("key=3時enumMap1的元素有 " + enumMap1); System.out.println(" 此時鍵值對個數為: " + enumMap1.size() + "\n"); enumMap1.put(ColorValues.RED, ColorValues.RED.getDescription() + Weeks[ColorValues.RED.ordinal()]); System.out.println("key=4時enumMap1的元素有 " + enumMap1); System.out.println(" 此時鍵值對個數為: " + enumMap1.size() + "\n"); enumMap1.put(ColorValues.WHITE, ColorValues.WHITE.getDescription() + Weeks[ColorValues.WHITE.ordinal()]); System.out.println("key=5時enumMap1的元素有 " + enumMap1); System.out.println(" 此時鍵值對個數為: " + enumMap1.size() + "\n"); enumMap1.put(ColorValues.YELLOW, ColorValues.YELLOW.getDescription() + Weeks[ColorValues.YELLOW.ordinal()]); System.out.println("key=6時enumMap1的元素有 " + enumMap1); System.out.println(" 此時鍵值對個數為: " + enumMap1.size() + "\n"); System.out .println("==========================判斷枚舉鍵值對================================"); System.out.println("判斷是否存在鍵" + ColorValues.BLUE); System.out.println("結果為:" + enumMap1.containsKey(ColorValues.BLUE)); System.out.println("判斷是否存在值'藍色星期二'"); System.out.println("結果為:" + enumMap1.containsValue("藍色星期二")); System.out .println("==========================刪除枚舉鍵值對================================"); enumMap1.remove(ColorValues.BLUE); System.out.println("剩余元素有:" + enumMap1); System.out.println(" 此時鍵值對個數為: " + enumMap1.size() + "\n"); System.out .println("==========================獲取鍵對應的值================================"); System.out.println(" 獲取RED對應的值,結果為: " + enumMap1.get(ColorValues.RED)); System.out .println("==========================清空枚舉鍵值對================================"); enumMap1.clear(); System.out.println(" 此時鍵值對個數為: " + enumMap1.size() + "\n"); } public static void main(String[] args) { getEnumMap(); } }
注:EnumMap可以用來實現23種設計模式中的命令模式(對於設計模式,后續會有詳細的筆記)
枚舉的高效運用之遍歷枚舉接口元素:
1.集合類的主要作用就是用來管理一組相關的對象,當需要查看、使用集合中的所有對象時可以使用枚舉接口對其進行遍歷。
2.實現了Enumeration接口的對象可以生成一系列元素,每次生成一個。
3.通過連續調用nextElement()方法可以連續獲得枚舉接口中的元素。但若枚舉接口已沒有元素,調用該方法會拋出異常。
故在這之前要先用hasMoreElement()進行判斷:
boolean hasMoreElements()
4.Collection類的靜態方法enumeration()可以用來將任意集合轉換成枚舉接口類型。
代碼實例:
1.利用SequenceInputStream方法合並文件
package com.xhj.Enum; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.SequenceInputStream; import java.util.ArrayList; import java.util.Collections; import java.util.Enumeration; import java.util.List; import java.util.Vector; /** * 利用SequenceInputStream方法合並文件 * * @author XIEHEJUN * */ public class MergeFiles { public static void main(String[] args) { String uri1 = "src/com/xhj/Enum/file1.txt"; String uri2 = "src/com/xhj/Enum/file2.txt"; String uri3 = "src/com/xhj/Enum/file3.txt"; List<InputStream> v = new ArrayList<InputStream>(); SequenceInputStream sis = null; OutputStream os = null; try { v.add(new FileInputStream(uri1)); v.add(new FileInputStream(uri2)); Enumeration<InputStream> e = Collections.enumeration(v); sis = new SequenceInputStream(e); os = new FileOutputStream(new File(uri3)); int len = 0; byte[] bu = new byte[1024]; while ((len = sis.read(bu)) != -1) { os.write(bu, 0, len); } } catch (FileNotFoundException e1) { e1.printStackTrace(); } catch (IOException e1) { e1.printStackTrace(); } finally { try { sis.close(); os.close(); } catch (IOException e) { e.printStackTrace(); } } } }
2.用IO流實現文件合並
package com.xhj.io; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStream; /** * 用IO流的方法合並文件 * * @author XIEHEJUN * */ public class MergeFiles { public static File createFile(String uri, String contents) { File file = new File(uri); try { OutputStream os = new FileOutputStream(uri); os.write(contents.getBytes()); os.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return file; } public static String getContents(File file) { StringBuffer sb = new StringBuffer(); try { if (file.exists()) { FileInputStream is = new FileInputStream(file); BufferedReader b_reader = new BufferedReader( new InputStreamReader(is)); String inLine = b_reader.readLine(); while (inLine != null) { // System.getProperty("line.separator")--獲取當前系統的換行符 sb.append(inLine + System.getProperty("line.separator")); inLine = b_reader.readLine(); } b_reader.close(); is.close(); } } catch (Exception e) { e.printStackTrace(); } return sb.toString(); } public static void main(String[] args) { File file1 = createFile("src/com/xhj/io/file1.txt", "你好!"); File file2 = createFile("src/com/xhj/io/file2.txt", "我是和佑!"); File file3 = createFile("src/com/xhj/io/file3.txt", "你呢?"); String content1 = mergeContents(getContents(file1), getContents(file2)); String content2 = mergeContents(content1, getContents(file3)); createFile("src/com/xhj/io/file3.txt", content2); } /** * 合並內容 * * @param contents1 * @param contents2 * @return */ public static String mergeContents(String contents1, String contents2) { contents1 = contents1.replace("\r\n", ""); if (contents2.indexOf(contents1) == -1) { contents2 = contents1 + contents2; } return contents2; } }