一、理解枚举类型
枚举类型是Java 5中新增特性的一部分,它是一种特殊的数据类型,之所以特殊是因为它既是一种类(class)类型却又比类类型多了些特殊的约束,但是这些约束的存在也造就了枚举类型的简洁性、安全性以及便捷性。下面先来看看如何写一个枚举?
二、枚举的定义语法
在没有枚举类型时定义常量常见的方式
public class DayDemo {
public static final int MONDAY =1;
public static final int TUESDAY=2;
public static final int WEDNESDAY=3;
public static final int THURSDAY=4;
public static final int FRIDAY=5;
public static final int SATURDAY=6;
public static final int SUNDAY=7;
}
上述的常量定义常量的方式称为int枚举模式,这样的定义方式并没有什么错,但它存在许多不足,如在类型安全和使用方便性上并没有多少好处,如果存在定义int值相同的变量,容易混淆,因此这种方式在枚举出现后并不提倡,现在我们利用枚举类型来重新定义上述的常量,定义周一到周日的常量
//枚举类型,使用关键字enum
enum Day {
MONDAY, TUESDAY, WEDNESDAY,
THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
相当简洁,在定义枚举类型时我们使用的关键字是enum,与class关键字类似,只不过前者是定义枚举类型,后者是定义类类型。
枚举类型Day中分别定义了从周一到周日的值,这里要注意,值一般是大写的字母,多个值之间以逗号分隔。同时我们应该知道的是枚举类型可以像类(class)类型一样,定义为一个单独的文件,当然也可以定义在其他类内部,更重要的是枚举常量在类型安全性和便捷性都很有保证,如果出现类型问题编译器也会提示我们改进,但务必记住枚举表示的类型其取值是必须有限的,也就是说每个值都是可以枚举出来的,比如上述描述的一周共有七天。
以上是写法,写好后该如何使用呢?如下:
public class EnumDemo {
public static void main(String[] args){
//直接引用
Day day =Day.MONDAY;
}
}
就像上述代码那样,直接引用枚举的值即可,这便是枚举类型的最简单模型。
三、为什么可以这样用,看看枚举实现原理就知道了
我们大概了解了枚举类型的定义与简单使用后,现在有必要来了解一下枚举类型的基本实现原理。实际上在使用关键字enum创建枚举类型并编译后,编译器会为我们生成一个相关的类,这个类继承了Java API中的java.lang.Enum类,也就是说通过关键字enum创建枚举类型在编译后事实上也是一个类类型而且该类继承自java.lang.Enum类。我们可以看看反编译的结果!
结论:从反编译的代码可以看出编译器确实帮助我们生成了一个Day类而且该类继承自java.lang.Enum类,该类是一个抽象类,除此之外,编译器还帮助我们生成了7个Day类型的实例对象分别对应枚举中定义的7个日期。还为我们生成了两个静态方法,分别是values()和 valueOf(),到此我们也就明白了,使用关键字enum定义的枚举类型,在编译期后,也将转换成为一个实实在在的类,而在该类中,会存在每个在枚举类型中定义好常量的对应实例对象,如上述的MONDAY枚举类型对应public static final Day MONDAY;
四、编译器生成的Values方法与ValueOf方法
values()方法和valueOf(String name)方法是编译器生成的static方法,后面我们自己定义的枚举类的父类Enum的分析中,在Enum类中并没出现values()方法,但valueOf()方法还是有出现的,只不过编译器生成的valueOf()方法需传递一个name参数,而Enum自带的静态方法valueOf()则需要传递两个方法,从前面反编译后的代码可以看出,编译器生成的valueOf方法最终还是调用了Enum类的valueOf方法,下面通过代码来演示这两个方法的作用:
Day[] days2 = Day.values();
System.out.println("day2:"+Arrays.toString(days2));
Day day = Day.valueOf("MONDAY");
System.out.println("day:"+day);
输出结果:
day2:[MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY]
day:MONDAY
从结果可知道,values()方法的作用就是获取枚举类中的所有变量,并作为数组返回,而valueOf(String name)方法与Enum类中的valueOf方法的作用类似根据名称获取枚举变量,只不过编译器生成的valueOf方法更简洁些只需传递一个参数。
五、Enum抽象类常见方法
Enum是所有 Java 语言枚举类型的公共基本类(注意Enum是抽象类),以下是它的常见方法:
ordinal()方法,该方法获取的是枚举变量在枚举类中声明的顺序,下标从0开始,如日期中的MONDAY在第一个位置,那么MONDAY的ordinal值就是0,如果MONDAY的声明位置发生变化,那么ordinal方法获取到的值也随之变化,注意在大多数情况下我们都不应该首先使用该方法,毕竟它总是变幻莫测的。
compareTo(E o)方法则是比较枚举的大小,注意其内部实现是根据每个枚举的ordinal值大小进行比较的。
name()方法与toString()几乎是等同的,都是输出变量的字符串形式。
valueOf(Class enumType, String name)方法则是根据枚举类的Class对象和枚举名称获取枚举常量,注意该方法是静态的。
下面的代码演示了上述方法:
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};
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("-------------------------------------");
System.out.println("days[0].toString():"+days[0].toString());
System.out.println("days[1].toString():"+days[1].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);
}
六、枚举的进阶用法
向enum类添加方法与自定义属性和构造函数 重新定义一个日期枚举类,带有desc成员变量描述该日期的对于中文描述,同时定义一个getDesc方法,返回中文描述内容,自定义私有构造函数,在声明枚举实例时传入对应的中文描述,代码如下:
public enum Day2 {
MONDAY("星期一",1),
TUESDAY("星期二",2),
WEDNESDAY("星期三",3),
THURSDAY("星期四",4),
FRIDAY("星期五",5),
SATURDAY("星期六",6),
SUNDAY("星期日",7);//记住要用分号结束
private String desc;//文字描述
private Integer code; //对应的代码
/**
* 私有构造,防止被外部调用
* @param desc
*/
private Day2(String desc,Integer code){
this.desc=desc;
this.code=code;
}
/**
* 定义方法,返回描述,跟常规类的定义没区别
* @return
*/
public String getDesc(){
return desc;
}
/**
* 定义方法,返回代码,跟常规类的定义没区别
* @return
*/
public int getCode(){
return code;
}
public static void main(String[] args){
for (Day2 day:Day2.values()) {
System.out.println("name:"+day.name()+
",desc:"+day.getDesc());
}
}
输出结果:
name:MONDAY,desc:星期一
name:TUESDAY,desc:星期二
name:WEDNESDAY,desc:星期三
name:THURSDAY,desc:星期四
name:FRIDAY,desc:星期五
name:SATURDAY,desc:星期六
name:SUNDAY,desc:星期日
原文链接:https://blog.csdn.net/weixin_43610698/article/details/90737759
一,枚举算法的思想:
1,枚举算法的定义:
在进行归纳推理时,如果逐个考察了某类事件的所有可能情况,因而得出一般结论,那么该结论是可靠 的,这种归纳方法叫做枚举法。
2,枚举算法的思想是:
将问题的所有可能的答案一一列举,然后根据条件判断此答案是否合适,保留合适的,舍弃不合适的。
3,使用枚举算法解题的基本思路如下:
(1)确定枚举对象、范围和判定条件。
(2)逐一枚举可能的解并验证每个解是否是问题的解。
4,枚举算法步骤:
(1)确定解题的可能范围,不能遗漏任何一个真正解,同时避免重复。
(2)判定是否是真正解的方法。
(3)为了提高解决问题的效率,使可能解的范围将至最小,
5,枚举算法的流程图如下所示:
二,枚举算法实例
例一:百钱买百鸡
1,问题描述:
公鸡每只5元,母鸡每只3元,三只小鸡1元,用100元买100只鸡,问公鸡、母鸡、小鸡各多少只?
2,算法分析:
利用枚举法解决该问题,以三种鸡的个数为枚举对象,分别设为mj,gj和xj,用三种鸡的总数 (mj+gj+xj=100)和买鸡钱的总数(1/3*xj+mj * 3+gj * 5=100)作为判定条件,穷举各种鸡的个数。
例二:使用枚举法解决“填写运算符问题”
1,问题描述:在下面的算式中,添加“+”、“-”,“*”,“/”,4个运算符,使得这个式子成立。
5 5 5 5 5=5
2,算法分析:
上述式子左侧有5个数字,一共需要4个运算符。根据题目要求,两个数字之间的运算符只能有4中选择。在 具体编程时,可以通过循环来填入各种运算符,然后再判断算式左侧的值是否等于右侧的值。并保证,当填入的 是除号时,则右侧的数不能为0,并且乘除的优先级高于加减的优先级。
原文链接:https://blog.csdn.net/qq_32211827/article/details/72970404
百钱买百鸡代码实现
public class p1002 {
public static void main(String[] args) {
for (int i=0;i<=20;i++){
for (int j=0;j<=33;j++){
for (int k=0;k<=300;k=k+3){
if ((i+j+k==100)&&(i*5+j*3+(k/3)==100)){
System.out.println("公鸡"+i+"只"
+"母鸡"+j+"只"
+"小鸡"+k+"只");
}
}
}
}
}
}
【问题描述】设有1g、2g、3g、5g、10g、20g的砝码各若干枚(其总重<=1000),求用这些砝码能称出不同的重量个数。
【文件输入】输入1g、2g、3g、5g、10g、20g的砝码个数。
【文件输出】输出能称出不同重量的个数。
【样例输入】1 1 0 0 0 0
【样例输出】3
public class 砝码称重 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int[] arr1=new int[1001];
int[] arr2=new int[7],arr4=new int[7];
int[] arr3={0,1,2,3,5,10,20};
for (int i=1;i<arr2.length;i++){
arr2[i]=sc.nextInt();
}
for (arr4[1]=0;arr4[1]<=arr2[1];arr4[1]++){
for (arr4[2]=0;arr4[2]<=arr2[2];arr4[2]++){
for (arr4[3]=0;arr4[3]<=arr2[3];arr4[3]++){
for (arr4[4]=0;arr4[4]<=arr2[4];arr4[4]++){
for (arr4[5]=0;arr4[5]<=arr2[5];arr4[5]++){
for (arr4[6]=0;arr4[6]<=arr2[6];arr4[6]++){
int sum=0;
for (int i=1;i<arr2.length;i++){
sum+=arr4[i]*arr3[i];
arr1[sum]=1;
}
}
}
}
}
}
}
int num=0;
for (int i=1;i<arr1.length;i++){
if (arr1[i]==1){
num++;
}
}
System.out.println(num);
}
}