JAVA提高之枚举类

最近学习JAVA枚举类相关知识,写篇博客记录一下,主要从三个方面来介绍枚举类,第一,为什么要用枚举类,第二,枚举类的定义,第三,枚举类的常用方法。

(一)为什么要用枚举类?

在设计程序时,通常有一些变量的名称数目性质时稳定的,比如说一年四季,一周七天,性别男女等,这些常量是有限且稳定的,在通常定义的方法;

private static fianl FIRSTSEASON=SPRING;
private static fianl SECONDSEASON=SUMMER;
private static fianl THIRDSEASON=AUTUMN;
private static fianl FOURSEASON=WINTER;

然而,大部分数据量比较庞大时,这样的定义显得繁琐且复杂,因而使用枚举类,能够定义这些常用的变量。

/**
 * 枚举类的后缀建议为Enum,枚举类型的实例对象建议全大写(这样做符合JAVA的规范)
 */
public enum SeasonEnum{  
  SPRING,SUMMER,AUTUMN,WINTER
}

 当需要定义一组常量时,强烈建议使用枚举类,枚举类的属性

  • 枚举类对象的属性不应允许被改动, 所以应该使用 private final 修饰
  • 枚举类的使用 private final 修饰的属性应该在构造器中为其赋值
  • 若枚举类显式的定义了带参数的构造器, 则在列出枚举值时也必须对应的 传入参数
     

(二)枚举类的定义

      枚举(enum)类型是Java 5新增的特性,它是一种新的类型,允许用常量来表示特定的数据片断,而且全部都以类型安全的形式来表示。

      关键字enum可以将一组具名的值的有限集合创建为一个新的类型,而这些具名的值可以作为常规的程序组件使用。

      

public class EnumDemo {

    public static void main(String[] args){
        //直接引用
        Day day =Day.MONDAY;
    }

}
//定义枚举类型,一周七天的枚举类
enum Day {
    MONDAY, TUESDAY, WEDNESDAY,
    THURSDAY, FRIDAY, SATURDAY, SUNDAY
}

(三)枚举类的常用方法

Enum类的主要方法:

  1.  values()方法:返回枚举类型的对象数组。该方法可以很方便地遍历所有的 枚举值。
  2.  valueOf(String str):可以把一个字符串转为对应的枚举类对象。要求字符 串必须是枚举类对象的“名字”。如不是,会有运行时异常: IllegalArgumentException。
  3.  toString():返回当前枚举类对象常量的名称
 package strings;

/**
 * Created with IntelliJ IDEA.
 * User:  yongping Li
 * Date: 2020/11/9
 * Time: 14:36
 * Description: No Description
 */

public class EnumDemo {

    public static void main(String[] args){

        //创建枚举数组
        Day[] days=new Day[]{Day.MONDAY, Day.TUESDAY, Day.WEDNESDAY,
                Day.THURSDAY, Day.FRIDAY, Day.SATURDAY, Day.SUNDAY};
        System.out.println("----------输出枚举类的所有元素及其下标-------------");
        for (int i = 0; i <days.length ; i++) {
            System.out.println("day["+i+"].ordinal():"+days[i].ordinal());
        }

        System.out.println("----------同一枚举类元素的比较-----------------");
        //通过compareTo方法比较,实际上其内部是通过ordinal()值比较的
        System.out.println("days[0].compareTo(days[1]):"+days[0].compareTo(days[1]));
        System.out.println("days[0].compareTo(days[1]):"+days[0].compareTo(days[2]));

        //获取该枚举对象的Class对象引用,当然也可以通过getClass方法
        Class<?> clazz = days[0].getDeclaringClass();
        System.out.println("clazz:"+clazz);

        System.out.println("----------输出枚举类不同下标的元素-----------------");

        //name()
        System.out.println("days[0].name():"+days[0].name());
        System.out.println("days[1].name():"+days[1].name());
        System.out.println("days[2].name():"+days[2].name());
        System.out.println("days[3].name():"+days[3].name());

        System.out.println("-------------枚举类的tostring方法------------------");

        System.out.println("days[0].toString():"+days[0].toString());
        System.out.println("days[1].toString():"+days[1].toString());
        System.out.println("days[2].toString():"+days[2].toString());
        System.out.println("days[3].toString():"+days[3].toString());

        System.out.println("------------枚举类元素的名字-----------------");

        Day d=Enum.valueOf(Day.class,days[0].name());
        Day d2=Day.valueOf(Day.class,days[0].name());
        System.out.println("d:"+d);
        System.out.println("d2:"+d2);

        System.out.println("枚举类的哈希值为"+days.hashCode());
        System.out.println("枚举类的长度为"+days.length);
    }

}
enum Day {
    MONDAY, TUESDAY, WEDNESDAY,
    THURSDAY, FRIDAY, SATURDAY, SUNDAY
}

运行结果如下:

----------输出枚举类的所有元素及其下标-------------
day[0].ordinal():0
day[1].ordinal():1
day[2].ordinal():2
day[3].ordinal():3
day[4].ordinal():4
day[5].ordinal():5
day[6].ordinal():6
----------同一枚举类元素的比较-----------------
days[0].compareTo(days[1]):-1
days[0].compareTo(days[1]):-2
clazz:class strings.Day
----------输出枚举类不同下标的元素-----------------
days[0].name():MONDAY
days[1].name():TUESDAY
days[2].name():WEDNESDAY
days[3].name():THURSDAY
-------------枚举类的tostring方法------------------
days[0].toString():MONDAY
days[1].toString():TUESDAY
days[2].toString():WEDNESDAY
days[3].toString():THURSDAY
------------枚举类元素的名字-----------------
d:MONDAY
d2:MONDAY
枚举类的哈希值为1956725890
枚举类的长度为7

Process finished with exit code 0

运行实例:

package arrays;//: enumerated/EnumClass.java
// Capabilities of the Enum class


enum Shrubbery { GROUND, CRAWLING, HANGING }

public class EnumClass {
  public static void main(String[] args) {
    System.out.println("---------利用循环输出枚举类的每个是及其特性---------");
    for(Shrubbery s : Shrubbery.values()) {
      System.out.println(s + " ordinal: " + s.ordinal());
      System.out.println(s.compareTo(Shrubbery.CRAWLING) + " ");
      System.out.println(s.equals(Shrubbery.CRAWLING) + " ");
      System.out.println(s == Shrubbery.CRAWLING);
      System.out.println(s.getDeclaringClass());
      System.out.println(s.name());
      System.out.println(s.hashCode());
      System.out.println("----------------------");
    }
    // Produce an enum value from a string name:
    for(String s : "HANGING CRAWLING GROUND".split(" ")) {
      Shrubbery shrub = Enum.valueOf(Shrubbery.class, s);
      System.out.println(shrub);
    }
  }
} /* Output:
GROUND ordinal: 0
-1 false false
class Shrubbery
GROUND
----------------------
CRAWLING ordinal: 1
0 true true
class Shrubbery
CRAWLING
----------------------
HANGING ordinal: 2
1 false false
class Shrubbery
HANGING
----------------------
HANGING
CRAWLING
GROUND
*///:~

运行结果为:

---------利用循环输出枚举类的每个是及其特性---------
GROUND ordinal: 0
-1 
false 
false
class arrays.Shrubbery
GROUND
1163157884
----------------------
CRAWLING ordinal: 1
0 
true 
true
class arrays.Shrubbery
CRAWLING
1956725890
----------------------
HANGING ordinal: 2
1 
false 
false
class arrays.Shrubbery
HANGING
356573597
----------------------
HANGING
CRAWLING
GROUND

Process finished with exit code 0

(四)Java常用方法举例

<1>保存常量

public enum Color {  
  RED, GREEN, BLANK, YELLOW  
} 

<2>和switch连用

package arrays;//: enumerated/TrafficLight.java
// Enums in switch statements.


// Define an enum type:
enum Signal { GREEN, YELLOW, RED, }

public class TrafficLight {
  Signal color = Signal.RED;
  public void change() {
    switch(color) {
      // Note that you don't have to say Signal.RED
      // in the case statement:
      case RED:    color = Signal.GREEN;
                   break;
      case GREEN:  color = Signal.YELLOW;
                   break;
      case YELLOW: color = Signal.RED;
                   break;
    }
  }
  public String toString() {
    return "The traffic light is " + color;
  }
  public static void main(String[] args) {
    TrafficLight t = new TrafficLight();
    for(int i = 0; i < 7; i++) {
      System.out.println(t);
      t.change();
    }
  }
} /* Output:
The traffic light is RED
The traffic light is GREEN
The traffic light is YELLOW
The traffic light is RED
The traffic light is GREEN
The traffic light is YELLOW
The traffic light is RED
*///:~

运行结果为:

 The traffic light is RED
The traffic light is GREEN
The traffic light is YELLOW
The traffic light is RED
The traffic light is GREEN
The traffic light is YELLOW
The traffic light is RED

Process finished with exit code 0

(3)向枚举类中添加新方法

除了不能继承一个枚举类之外,可以将enum看成一个常规的类,也即是说可以向枚举类中和添加新方法。

public enum Color {  
    RED("红色", 1), GREEN("绿色", 2), BLANK("白色", 3), YELLO("黄色", 4);  
    // 成员变量  
    private String name;  
    private int index;  
    // 构造方法  
    private Color(String name, int index) {  
        this.name = name;  
        this.index = index;  
    }  


    // 普通方法 自定义getname方法 
    public static String getName(int index) {  
        for (Color c : Color.values()) {  
            if (c.getIndex() == index) {  
                return c.name;  
            }  
        }  
        return null;  
    }  
    // get set 方法  
    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;  
    }  
}  

(4)覆盖原有方法

package arrays;

//: enumerated/SpaceShip.java
public enum SpaceShip {
  SCOUT, CARGO, TRANSPORT, CRUISER, BATTLESHIP, MOTHERSHIP;
  //自定义tostring()方法
  public String toString() {
    String id = name();
    String lower = id.substring(1).toLowerCase();
    return id.charAt(0) + lower;
  }
  public static void main(String[] args) {
    for(SpaceShip s : values()) {
      System.out.println(s);
    }
  }
} /* Output:
Scout
Cargo
Transport
Cruiser
Battleship
Mothership
*///:~

运行结果为:

Scout
Cargo
Transport
Cruiser
Battleship
Mothership

Process finished with exit code 0

(5)实现接口

实现接口的枚举类

  • 和普通 Java 类一样,枚举类可以实现一个或多个接口
  • 若每个枚举值在调用实现的接口方法呈现相同的行为方式,则只 要统一实现该方法即可。
  • 若需要每个枚举值在调用实现的接口方法呈现出不同的行为方式, 则可以让每个枚举值分别来实现该方法
 package arrays;

/**
 * Created with IntelliJ IDEA.
 * User:  yongping Li
 * Date: 2020/11/10
 * Time: 16:22
 * Description: No Description
 */

 interface DayInterface {

    public String getDay();
}

public enum MyDay implements DayInterface{

    MONDAY(1,"星期一"),THUSDAY(2,"星期二");//这个后面必须有分号

    private int code;
    private String name;
    private MyDay(int code,String name) {
        this.code = code;
        this.name = name;
    }

    public int getCode() {
        return code;
    }
    public String getName() {
        return name;
    }
    public void setCode(int code) {
        this.code = code;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        // TODO Auto-generated method stub
        return this.getName()+"---"+this.getCode();
    }

    @Override
    public String getDay() {
        return this.getName();
    }

    public static void main(String[] args) {
        System.out.println(MyDay.THUSDAY.getDay());
        System.out.println(MyDay.MONDAY.getDay());
    }
}

运行结果为:

猜你喜欢

转载自blog.csdn.net/weixin_41792162/article/details/109577731
今日推荐