Effective Java (ENUM篇)
我们存放一些静态变量,像是一些变量和设置,等等等等,我们尽量使用ENUM,因为ENUM是不可实例化和继承的,所以他很安全,它是在程序一开始运行的时候进行一些编译,修改ENUM不需要再次编译。
在什么时候用ENUM呢。摘录如下。
Use enums when you want to define a range of values that something can be. Colour is an obvious example like: public enum Colour
{
White,
Red,
Blue
}
Or maybe a set of possible things like: (Example I stole from here as I'm lazy) [FlagsAttribute]
enum DistributedChannel
{
None = 0,
Transacted = 1,
Queued = 2,
Encrypted = 4,
Persisted = 16,
FaultTolerant = Transacted | Queued | Persisted
}
Constants should be for a single value, like PI. There isn't a range of PI values, there is just PI.
一个简单应用
public enum CircleArea {
CIRCLEONE(1.2),
CIRCLETWO(2.5),
CIRCLETHREE(3.5);
private final double r;
private static final double PI=3.14;
CircleArea(double r) {
this.r=r;
}
public double R(){
return r;
}
public double Area(){
return r*r*PI;
}
public double SomeArea(int Some){
return Some*r*r*PI;
}
}
测试
for (CircleArea c:CircleArea.values() ){
System.out.println(c+" "+c.R()+" "+c.SomeArea(3)+"");
}
使用ENUM的时候,如果enum里面有ABstract ,则声明的时候也必须要有,所以以下尽量使用Operation2的形式。
public enum Operation {
PLUS, MINUS, TIMES, DIVDE;
double apply(double x, double y) {
switch (this) {
case PLUS:
return x + y;
case MINUS:
return x - y;
case TIMES:
return x * y;
case DIVDE:
return x / y;
}
throw new AssertionError("未定义类型" + this);
}
}
public enum Operation2 {
PLUS {
double apply(double x, double y) {
return x + y;
}
},
MINUS {
double apply(double x, double y) {
return x - y;
}
},
TIMES {
double apply(double x, double y) {
return x * y;
}
},
DIVIDE {
double apply(double x, double y) {
return x / y;
}
};
abstract double apply(double x, double y);
}
/////////////////////////带符号输出的
public enum Operation3 {
PLUS("+") {
double apply(double x, double y) {
return x + y;
}
},
MINUS("-") {
double apply(double x, double y) {
return x - y;
}
},
TIMES("*") {
double apply(double x, double y) {
return x * y;
}
},
DIVIDE("/") {
double apply(double x, double y) {
return x / y;
}
};
private final String symbol;
Operation3(String symbol) {
this.symbol = symbol;
}
@Override public String toString(){
return symbol;
}
abstract double apply(double x, double y);
}
除了EnumSet和EnumMap,都不要使用ordinals。
public enum WrongIdEnum {
FIRST,SECOND,THIRD;
public int getId(){
return ordinal()+1;
}
}
public enum IdEnum {
FIRST(1),SECOND(2),THIRD(3);
private final int id;
IdEnum(int id){
this.id=id;
}
public int getId(){
return id;
}
}
上面两个Enum都可以实现返回ID的功能,但是千万不要使用第一个类型,因为第一个类型非常不方便增删,如果我在中间删掉一个定量,因为ordinals代表的是当前在Enum的排序第几个,后面所代表的意义全部会乱。
在JAVA中,尽量不要使用位操作定量,可以使用EnumSet来替换,EnumSet比较安全且高效,继承了Enum的所有优点,什么是位操作定量,需要了解一下。附上EnumSet的一个实现。
public enum Day {
MONDAY, TUESDAY, WEDNESDAY,
THURSDAY, FRIDAY, SATURDAY, SUNDAY;
}
public class Worker {
private String name;
private Set<Day> avalibleDay;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<Day> getAvalibleDay() {
return avalibleDay;
}
public void setAvalibleDay(Set<Day> avalibleDay) {
this.avalibleDay = avalibleDay;
}
public Worker(String name, Set<Day> avalibleDay) {
super();
this.name = name;
this.avalibleDay = avalibleDay;
}
}
public static void getNoDay(Worker[] work){//哪天都没人来
Set<Day> days = EnumSet.allOf(Day.class);
for(Worker w:work){
days.removeAll(w.getAvalibleDay());//在这里体现“位”操作
}
System.out.println("都没人在的是"+days);
}
public static void getEveryDay(Worker[] work){//哪天都来人
Set<Day> days = EnumSet.allOf(Day.class);
for(Worker w:work){
days.retainAll(w.getAvalibleDay());//在这里体现“位”操作
}
System.out.println("都有人在的是"+days);
}
Worker[] workers = new Worker[]{
new Worker("张三", EnumSet.of(
Day.TUESDAY, Day.WEDNESDAY, Day.FRIDAY)),
new Worker("李四", EnumSet.of(
Day.TUESDAY, Day.THURSDAY, Day.SATURDAY)),
new Worker("王五", EnumSet.of(
Day.TUESDAY, Day.THURSDAY)),
};
MyTestMethod.getNoDay(workers);
MyTestMethod.getEveryDay(workers);
//输出
//都没人在的是[MONDAY, SUNDAY]
//都有人在的是[TUESDAY]
用接口模拟可扩展Enum
设计枚举的时候最好不要设计可扩展性,如果实在要设计,可以使用接口的方式实现。
public interface OperationInterface {
double apply(double x,double y);
}
public enum OperationEnum implements OperationInterface {//可以设计很多个implements OperationInterface的枚举,实现枚举的变相扩展
PLUS("+") {
@Override
public double apply(double x, double y) {
return x + y;
}
},
MINUS("-") {
@Override
public double apply(double x, double y) {
return x - y;
}
};
private final String symbol;
OperationEnum(String symbol) {
this.symbol = symbol;
}
@Override
public String toString() {
/**
* @Description:
* @author: shengzhizhi
* @modifier:
* @date: 2018年8月20日 下午5:58:21
*/
return this.symbol;
}
}
public class TestEnumForImplement {
public static void main(String[] args) {
double d1 = 1.2;
double d2 = 2.2;
say(Arrays.asList(OperationEnum.values()),d1,d2);
}
public static void say(Collection<? extends OperationInterface> opSet, double x, double y) {
for (OperationInterface e : opSet) {
System.out.printf("the methos is %s, result is %f%n", e, e.apply(x, y));
}
}
}
Effective Java (ENUM篇)的更多相关文章
- [Effective Java] 创建和销毁对象篇
[Effective Java] 创建和销毁对象篇 1. 优先考虑用静态工厂方法代替构造器 优点: - 静态工厂方法相比于构造器,它们有名称 - 不需要每次在使用的时候创建一个对象 - 可以返回原返回 ...
- Effective Java 第二版 Enum
/** * Effective Java 第二版 * 第30条:用enum代替int常量 */ import java.util.HashMap;import java.util.Map; publi ...
- Effective Java通俗理解(持续更新)
这篇博客是Java经典书籍<Effective Java(第二版)>的读书笔记,此书共有78条关于编写高质量Java代码的建议,我会试着逐一对其进行更为通俗易懂地讲解,故此篇博客的更新大约 ...
- Effective Java通俗理解(下)
Effective Java通俗理解(上) 第31条:用实例域代替序数 枚举类型有一个ordinal方法,它范围该常量的序数从0开始,不建议使用这个方法,因为这不能很好地对枚举进行维护,正确应该是利用 ...
- effective java笔记之单例模式与序列化
单例模式:"一个类有且仅有一个实例,并且自行实例化向整个系统提供." 单例模式实现方式有多种,例如懒汉模式(等用到时候再实例化),饿汉模式(类加载时就实例化)等,这里用饿汉模式方法 ...
- Effective Java通俗理解(上)
这篇博客是Java经典书籍<Effective Java(第二版)>的读书笔记,此书共有78条关于编写高质量Java代码的建议,我会试着逐一对其进行更为通俗易懂地讲解,故此篇博客的更新大约 ...
- 《Effective Java》读书笔记(一)之创建和销毁对象
最近在研读<Effective Java>一书,读书不做点笔记,感觉很容易就忘掉,于是用本篇博客来记录阅读此书的笔记. 郑重声明: 由于是<Effective Java>一书的 ...
- 如何创建和销毁对象(Effective Java 第二章)
最近有在看Effective Java,特此记录下自己所体会到的东西,写篇博文会更加的加深印象,如有理解有误的地方,希望不吝赐教. 这章主题主要是介绍:何时以及如何创建对象,何时以及如何避免创建对象, ...
- 简单认识java enum枚举
什么是枚举 枚举是java5中新增的特性,他是一个特殊的数据类型,他的特殊性在于他既是一种类类型,又比类类型多了安全性,简洁性,便捷性.java枚举类型是功能十分强大齐全的类,功能比其他语言中的对等物 ...
- Effective Java —— 用私有构造器或枚举类型强化单例属性
本文参考 本篇文章参考自<Effective Java>第三版第三条"Enforce the singleton property with a private construc ...
随机推荐
- linux搭建smb、挂载smb、Windows共享
实现Linux系统之间共享文件资源以及在Linux系统与Windows系统之间共享文件 Samba软件包的构成 服务端:samba 客户端:samba-client 公共组件:samba-common ...
- hihocoder 1513 小Hi的烦恼 (bitset优化)
大意: n个人, 5门课, 给定每个人每门课的排名, 对于每个人输出有多少人5门课都比他差. 明显是个5维偏序问题, 题目有保证排名均不同, 可以用bitset优化为$O(\frac{n^2}{\om ...
- 4月24 php基础及函数的应用
PHP是一种被广泛认可应用,运行在服务端的脚本语言,PHP需要安转PHP应用程序服务器去解释执行,是用来协助Web服务器工作的编程语言,因此所写的任何代码只有在www文件下的才能实施预览.PHP是一种 ...
- PAT 1027 Colors in Mars
1027 Colors in Mars (20 分) People in Mars represent the colors in their computers in a similar way ...
- InnoDB存储引擎介绍-(5) Innodb逻辑存储结构
如果创建表时没有显示的定义主键,mysql会按如下方式创建主键: 首先判断表中是否有非空的唯一索引,如果有,则该列为主键. 如果不符合上述条件,存储引擎会自动创建一个6字节大小的指针. 当表中有多个非 ...
- CompareTo 基于的排序算法
CompareTo 基于的排序算法(高级排序) 这个是今天学习MapReduce时发现的,自定义类后实现了WritableComparable<>接口后实现了接口中的compareTo方法 ...
- js浮点数相加、减、乘、除精确计算
js 浮点数计算时 ,无缘无辜 后边冒出一堆 小数点………… 貌似js本身的问题,类型不定?????? 只能自己写函数处理.. http://blog.csdn.net/w4bobo/article ...
- 线程池 execute 和 submit 的区别
代码示例: public class ThreadPool_Test { public static void main(String[] args) throws InterruptedExcept ...
- iptables报错:Couldn't load target `accept':/lib64/iptables/libipt_accept.so: cannot open shared object file: No such file or directory
语句:iptables -A INPUT -s 134.192.204.235 -p TCP --dport 11211 -j accept 报错:Couldn't load target `acce ...
- Java技巧之双括弧初始化
由于Java语言的集合框架中(collections, 如list, map, set等)没有提供任何简便的语法结构,这使得在建立常量集合时的工作非常繁索.每次建立时我们都要做: 定义一个临时的集合类 ...