JavaSE基礎:枚舉類型

枚舉類型(Enum)

在C語言中存在一個枚舉類型,經過此類型能夠限制一個內容的取值範圍,可是在JDK1.5以前,Java中並並不存在枚舉的類型,因此不少之間已經習慣了使用枚舉類型操做的開發人員就感受很不適應,爲了解決這個問題(或者說吸引部分客戶),因此在JDK1.5以後就加入了枚舉類型。java

我我的而言,自己就是從Java學起,實際上是否使用枚舉類型看本身的習慣就能夠,對於我來講有的時候枚舉類型就有點雞肋的感受,我可使用別的方式實現相似的枚舉。數組

情景模式說明,咱們平時可能要獲取星期幾,可是咱們獲取的是數組1-7的形式,那麼咱們就須要對起進行處理,實現代碼以下。ide

1.簡單程序實現枚舉功能

請注意關鍵的問題,咱們須要限制取值的範圍!函數

package com.shxt.demo01;

public class Week {
    //定義七個星期的對象
    public static final Week SUNDAY = new Week("星期日");
    public static final Week MONDAY = new Week("星期一");
    public static final Week TUESDAY = new Week("星期二");
    public static final Week WEDNESDAY = new Week("星期三");
    public static final Week THURSDAY = new Week("星期四");
    public static final Week FRIDAY = new Week("星期五");
    public static final Week SATURDAY = new Week("星期六");

    private String date;

    //請注意這裏使用的私有構造函數,沒法在外部進行實例化操做
    private Week(String date){
        this.date = date;
    }

    public String getDate() {
        return date;
    }

    public void setDate(String date) {
        this.date = date;
    }

    //獲取日期數組,從固定的星期中獲取數據
    public static Week getInstance(int week){
        switch (week){
            case 1:
                return SUNDAY;
            case 2:
                return MONDAY;
            case 3:
                return TUESDAY;
            case 4:
                return WEDNESDAY;
            case 5:
                return THURSDAY;
            case 6:
                return FRIDAY;
            case 7:
                return SATURDAY;
            default:
                return null;//錯誤的數值

        }
    }
}

複製代碼

測試代碼:測試

package com.shxt.demo01;

import java.util.Calendar;

public class WeekTest {
    public static void main(String[] args) {
        Calendar calendar = Calendar.getInstance();
        //System.out.println(calendar.get(Calendar.DAY_OF_WEEK));
        Week week = Week.getInstance(calendar.get(Calendar.DAY_OF_WEEK));
        if (week!=null){
            System.out.println(week.getDate());
        }
    }
}
複製代碼

代碼說明:this

以上程序將Week類中的構造方法進行私有化處理,以後在類中準備了若干個實例化對象,之後若是要獲取Week類的實例,只能使用MONDAY...SUNDAY7個對象,這樣就有效的限制了對象的取值範圍spa

以上使用的Week對象的指定範圍,咱們發現是經過一個個常量對每一個對象進行了編號。也就是一個個對象就至關於用常量進行了標識,因此按照這個思路咱們也能夠直接使用一個接口定義一組常量範圍(這種方法我的使用較少)rest

package com.shxt.demo02;

public interface Week {
    //自動補全public static final
    int SUNDAY = 1;
    int MONDAY = 2;
    int TUESDAY = 3;
    int WEDNESDAY = 4;
    int THURSDAY = 5;
    int FRIDAY = 6;
    int SATURDAY = 7;
}
複製代碼

可是經過接口的方式的枚舉會存在問題,會存在結果操做不正確的問題code

package com.shxt.demo02;

public class WeekTest {
    public static void main(String[] args) {
        System.out.println(Week.SATURDAY+Week.FRIDAY);//星期的數據相加,沒有該結果
    }
}
複製代碼

使用咱們這種方式,用戶想知道到底有多少星期可使用(假設你不知道),則實現的代碼會比較複雜,還有就是犧牲也比較大,因此在JDK1.5以後就專門解決了相似的問題。對象

2.定義枚舉類型

在JDK1.5以後,引入了一個新的關鍵字類型——enum,能夠直接定義枚舉類型,語法格式以下

public enum 枚舉類型名稱{
    枚舉對象1,枚舉對象2,枚舉對象3,...,枚舉對象N
}
複製代碼

示例1:定義一個枚舉類型

package com.shxt.demo03;
public enum Week {
    SUNDAY,MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY;
}

複製代碼

示例2:取出枚舉內容

package com.shxt.demo03;

public class Test01 {
    public static void main(String[] args) {
        Week w = Week.MONDAY;//獲得MONDAY
        System.out.println(w);
    }
}
/* 運行結果爲:MONDAY */
複製代碼

這個結果感受並無什麼卵用,咱們須要一步步來,使用此方式好處能夠避免以前使用接口方式的問題

package com.shxt.demo03;

public class Test02 {
    public static void main(String[] args) {
        System.out.println(Week.MONDAY+Week.FRIDAY);//錯誤
    }
}
複製代碼

枚舉類型的數據也可使用「枚舉.values()」的形式,將所有的枚舉類型變爲對象數組的形式,以後直接使用foreach進行操做。

示例3:使用foreach輸出枚舉內容

package com.shxt.demo03;

public class Test03 {
    public static void main(String[] args) {
        Week[] weeks = Week.values();
        for (Week w : weeks){
            System.out.println(w);
        }
    }
}
複製代碼

示例4:使用switch進行判斷

如今的一切都是簡單介紹,後面還有更加具體的介紹

package com.shxt.demo03;

public class Test04 {
    public static void main(String[] args) {
        Week[] weeks = Week.values();
        for (Week w : weeks){
            print(w);
        }
    }

    public static void print(Week week){
        switch (week){
            case SUNDAY:
                System.out.println("星期日");
                break;
            case MONDAY:
                System.out.println("星期一");
                break;
            case TUESDAY:
                System.out.println("星期二");
                break;
            case WEDNESDAY:
                System.out.println("星期三");
                break;
            case THURSDAY:
                System.out.println("星期四");
                break;
            case FRIDAY:
                System.out.println("星期五");
                break;
            case SATURDAY:
                System.out.println("星期六");
                break;
            default:
                System.out.println("什麼鬼???");
                break;

        }
    }
}

複製代碼

上述過程介紹的枚舉的使用在實際開發中應用是很是少的,做爲開發人員必需要進一步的深刻了解枚舉類型

3.進一步深刻枚舉類型

使用enum關鍵字能夠定義一個枚舉類型,實際上此關鍵字筆試的是java.lang.Enum類,使用enum聲明的枚舉類型就至關於定義一個類,而此類默認繼承了java.lang.Enum類

public abstract class Enum<E extends Enum<E>> extends Object implements Comparable<E>, Serializable 複製代碼
編號 方法名稱 類型 描述
1 protected Enum(String name,int ordinal) 構造 接收枚舉的名稱和枚舉常量建立枚舉對象
2 protected final Object clone()
throws CloneNotSupportedException
普通 克隆枚舉對象
3 public final int compareTo(E o) 普通 對象比較
4 public final boolean equals(Object other) 普通 比較兩個枚舉對象
5 public final int hashCode() 普通 返回枚舉常量的哈希碼
6 public final String name() 普通 返回此枚舉的名稱
7 public final int ordinal() 普通 返回枚舉常量的序數
8 public static <T extends Enum> T
valueOf(Class enumType, String name)
普通 返回帶指定名稱的指定枚舉類型的枚舉常量

示例1:獲取枚舉的信息

package com.shxt.demo03;

public enum Week {
    SUNDAY,MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY;
}
複製代碼
package com.shxt.demo03;

public class Test05 {
    public static void main(String[] args) {
        for (Week w : Week.values()) {
            System.out.println(w.ordinal()+"->"+w.name());
        }
    }
}
/** 運行結果: 0->SUNDAY 1->MONDAY 2->TUESDAY 3->WEDNESDAY 4->THURSDAY 5->FRIDAY 6->SATURDAY */
複製代碼

示例2:經過構造方法爲屬性賦值

每一個枚舉類中都有其指定的若干個對象,固然,每一個枚舉能夠包含多個屬性,必須在enum實例序列的最後添加一個分號,Java 要求必須先定義 enum 實例.

package com.shxt.demo04;

public enum Week {
    SUNDAY("星期日",7),MONDAY("星期一",1),TUESDAY("星期二",2),
    WEDNESDAY("星期三",3),THURSDAY("星期四",4),FRIDAY("星期五",5),SATURDAY("星期六",6);

    private String name;
    private int index;
    //構造方法
    private Week(String name,int index){
        this.name = name;
        this.index = index;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getIndex() {
        return index;
    }

    public void setIndex(int index) {
        this.index = index;
    }
}
複製代碼

Week枚舉類中增長了兩個屬性name和index,並經過私有構造方法設置name和index屬性的內容,由於Week中已經明肯定義了兩個參數的構造方法,因此枚舉內容必需要調用該構造方法.

package com.shxt.demo04;

public class Test05 {
    public static void main(String[] args) {
        for (Week w : Week.values()) {
            System.out.println("序號:"+w.ordinal()+" 枚舉名稱:"+w.name()+" 屬性name值:"+w.getName()+" 屬性index值:"+w.getIndex());
        }
    }
}
/** 運行結果爲: 序號:0 枚舉名稱:SUNDAY 屬性name值:星期日 屬性index值:7 序號:1 枚舉名稱:MONDAY 屬性name值:星期一 屬性index值:1 序號:2 枚舉名稱:TUESDAY 屬性name值:星期二 屬性index值:2 序號:3 枚舉名稱:WEDNESDAY 屬性name值:星期三 屬性index值:3 序號:4 枚舉名稱:THURSDAY 屬性name值:星期四 屬性index值:4 序號:5 枚舉名稱:FRIDAY 屬性name值:星期五 屬性index值:5 序號:6 枚舉名稱:SATURDAY 屬性name值:星期六 屬性index值:6 */
複製代碼

示例3:覆蓋枚舉方法toString

package com.shxt.demo05;

public enum Week {
    SUNDAY("星期日",7),MONDAY("星期一",1),TUESDAY("星期二",2),
    WEDNESDAY("星期三",3),THURSDAY("星期四",4),FRIDAY("星期五",5),SATURDAY("星期六",6);

    private String name;
    private int index;
    //構造方法
    private Week(String name, int index){
        this.name = name;
        this.index = index;
    }

    @Override
    public String toString() {
        return "Week{" +
                "name='" + name + '\'' +
                ", index=" + index +
                '}';
    }
}

複製代碼
package com.shxt.demo05;

public class Test05 {
    public static void main(String[] args) {
        for (Week w : Week.values()) {
            System.out.println(w);
        }
    }
}
/** 運行結果爲: Week{name='星期日', index=7} Week{name='星期一', index=1} Week{name='星期二', index=2} Week{name='星期三', index=3} Week{name='星期四', index=4} Week{name='星期五', index=5} Week{name='星期六', index=6} */
複製代碼

示例4:使用比較器

在Enum類中已經實現好了Comparable接口,因此枚舉類的內容自己是能夠進行排序的,只是測試一下結果,在類集的時候咱們介紹過TreeSet能夠直接進行排序,排序規則是根據Comparable接口完成的

package com.shxt.demo06;

public enum Week {
    SUNDAY,MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY;
}
複製代碼
import java.util.TreeSet;

public class Test01 {
    public static void main(String[] args) {
        Set<Week> weekSet = new TreeSet<>();
        //亂存數據
        weekSet.add(Week.FRIDAY);
        weekSet.add(Week.MONDAY);
        weekSet.add(Week.THURSDAY);
        weekSet.add(Week.WEDNESDAY);
        weekSet.add(Week.TUESDAY);
        weekSet.add(Week.SATURDAY);
        weekSet.add(Week.SUNDAY);
        for (Week w:weekSet){
            System.out.println(w.ordinal()+"-->"+w.name());
        }
    }
}
複製代碼

迭代出的數據順序是根據ordinal屬性進行排序的.

4.類集對枚舉的支持

(1)EnumMap

EnumMap是Map接口中的子類,因此自己仍是以Map的形式進行操做,key=>value

package com.shxt.demo07;

public enum  Color {
    RED,YELLOW,BLUE;
}
複製代碼
package com.shxt.demo07;

import java.util.EnumMap;
import java.util.Map;

public class EnumMapTest {
    public static void main(String[] args) {
        Map<Color,String> map = new EnumMap<Color, String>(Color.class);
        map.put(Color.RED,"紅色");
        map.put(Color.YELLOW,"黃色");
        map.put(Color.BLUE,"藍色");

        System.out.println("**********輸出所有的枚舉內容和其對應的值************");
        for(Color c : Color.values()){
            System.out.println(c.name()+" map中的value:"+map.get(c));
        }

        System.out.println("**********獲取所有的鍵值***************************");
        for (Color c : map.keySet()){
            System.out.println("KEY="+c.name());
        }
        System.out.println("**********獲取所有的內容***************************");
        for (String s : map.values()){
            System.out.println("Value="+s);
        }

    }
}

複製代碼

上述的代碼的應用場景我不太清楚,有清楚的請留言告知

(2)EnumSet

EnumSet是Set接口的子類,因此裏面的內容是沒法重複.使用EnumSet時不能直接使用關鍵字new爲其進行實例化,而是使用本類提供的靜態方法

序號 方法名稱 類型 描述
1 public static <E extends Enum<E>>
EnumSet<E> allOf(Class<E> elementType)
普通 將枚舉中的所有內容設置到EnumSet中
2 public static <E extends Enum<E>>
EnumSet<E> of(E first,E...rest)
普通 建立一個包含枚舉指定內容的EnumSet對象
3 public static <E extends Enum<E>>
EnumSet<E> copyOf(Collection<E> c)
普通 建立一個從指定Collection中指定的EnumSet對象
4 public static <E extends Enum<E>>
EnumSet<E> complementOf(EnumSet<E> s)
普通 建立一個其元素類型與指定枚舉 set 相同的枚舉
set,最初包含指定 set 中所不 包含的此類型的全部元素。
5 public static <E extends Enum<E>>
EnumSet<E> noneOf(Class<E> e)
普通 建立一個能夠接收指定類型的空集合

示例1:將所有的枚舉設置到EnumSet集合中

package com.shxt.demo08;

import java.util.EnumSet;

enum  Color {
    RED,YELLOW,BLUE;
}

public class DenumSetDemo01 {

    public static void main(String[] args) {
        EnumSet<Color> set = EnumSet.allOf(Color.class);//將枚舉的所有數據設置到EnumSet對象中

        for (Color c : set){
            System.out.println(c);
        }

    }

}
複製代碼

示例2:設置一個枚舉數據到EnumSet結合中

package com.shxt.demo08;

import java.util.EnumSet;

enum  Color {
    RED,YELLOW,BLUE;
}

public class DenumSetDemo02 {

    public static void main(String[] args) {
        EnumSet<Color> set = EnumSet.of(Color.YELLOW);//設置一個枚舉內容

        for (Color c : set){
            System.out.println(c);
        }

    }

}

複製代碼

示例3:只能放入指定的枚舉類型的集合

package com.shxt.demo08;

import java.util.EnumSet;

enum  Color {
    RED,YELLOW,BLUE;
}

public class DenumSetDemo03 {

    public static void main(String[] args) {
        EnumSet<Color> set = EnumSet.noneOf(Color.class);//建立一個能夠鍵入Color類型的對象
        set.add(Color.YELLOW);
        set.add(Color.BLUE);

        for (Color c : set){
            System.out.println(c);
        }

    }

}
複製代碼

其餘的方法就不作測試了,感受也沒有什麼實際的用處,這裏就省略...見諒

5.讓枚舉實現一個接口

枚舉類也能夠實現一個接口,可是由於接口中存在的都是抽線方法,因此枚舉類中的每一個對象必須分別實現接口中的抽象方法

package com.shxt.demo09;

interface Print{
    String getColor();
}

enum Color implements Print{
    RED{
        @Override
        public String getColor() {
            return "紅色";
        }
    },YELLOW{
        @Override
        public String getColor() {
            return "黃色";
        }
    },BLUE{
        @Override
        public String getColor() {
            return "藍色";
        }
    };
}

public class InterfaceEnumDemo01 {
    public static void main(String[] args) {
        for (Color c : Color.values()){
            System.out.println(c.getColor());
        }
    }
}

複製代碼

或者這樣寫也是能夠的

package com.shxt.demo10;

interface Print{
    String getColor();
}

enum Color implements Print {
   RED("紅色"),YELLOW("黃色"),BLUE("藍色");
   private String name;
   private Color(String name){
       this.name = name;
   }

    @Override
    public String getColor() {
        return this.name;
    }
}

public class InterfaceEnumDemo01 {
    public static void main(String[] args) {
        for (Color c : Color.values()){
            System.out.println(c.getColor());
        }
    }
}

複製代碼

6.在枚舉類中定義抽象方法

package com.shxt.demo11;


enum Color {
   RED("紅色") {
       @Override
       public String getColor() {
           return "紅紅=>"+this.name;
       }
   },YELLOW("黃色") {
        @Override
        public String getColor() {
            return "黃黃=>"+this.name;
        }
    },BLUE("藍色") {
        @Override
        public String getColor() {
            return "藍藍=>"+this.name;
        }
    };
   protected String name;
   private Color(String name){
       this.name = name;
   }


    public abstract String getColor() ;
}

public class AbstractEnumDemo01 {
    public static void main(String[] args) {
        for (Color c : Color.values()){
            System.out.println(c.getColor());
        }
    }
}

複製代碼
相關文章
相關標籤/搜索