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 ...
随机推荐
- hadoop 企业应用案例--大众点评
hadoop 企业应用案例--大众点评 http://f.dataguru.cn/thread-260531-1-1.html
- LCS(最长公共子序列)问题
例题见挑战程序设计竞赛P56 解释:子序列是从原序列中按顺序(可以跳着)抽取出来的,序列是不连续的,这是其和子串最大的区别: 我们可以定义dp数组为dp[i][j],表示的是s1-si和t1-ti对应 ...
- vim操作(待补充)
:wq 存盘 + 退出 (:w 存盘, :q 退出) :e 打开新文件 :q 退出 h.j.k.l,分别控制光标左.下.上.右移一格. 按Ctrl+B:屏幕往后移动一页.[常用] 按Ctrl+F:屏幕 ...
- 创建springboot的聚合工程(二)
前篇已经成功创建了springboot的聚合工程并成功访问,下面就要开始子工程木块之间的调用: springboot项目的特点,一个工程下面的类必须要放在启动类下面的子目录下面,否则,启动的时候会报错 ...
- Http简单解析过程
1.域名解析:浏览器先搜索自身的DNS缓存->搜索操作系统自身的DNS缓存(浏览器没有找到缓存或缓存已经失效)->读取本地host文件(操作系统DNS也没找到)->浏览器发起DNS的 ...
- [HNOI2002] 营业额统计
题目描述 Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况. Tiger拿出了公司的账本,账本上记录了公司成立以来每天的营业额.分析营业情况是 ...
- MapReduce分布式算法
一.MapReduce 有一种特殊的并行算法,就是分布式算法.在并行算法只需要两个到四个内核时,完全可以在笔记本电脑上运行,但是如果需要数百个内核,这种情况下,可让算法在多台计算机上运行. 假设你有一 ...
- 三、持久层框架(Hibernate)
一.Hibernate处理关系 关系主要有三种:1.多对一 2.一对多 3.多对多 1.多对一 一个Product对应一个Category,一个Category对应多个Product(一个产品对应一个 ...
- Hadoop格式化 From hu-hadoop1/192.168.11.11 to hu-hadoop2:8485 failed on connection exception: java.net.
192.168.11.12:8485: Call From hu-hadoop1/192.168.11.11 to hu-hadoop2:8485 failed on connection excep ...
- 【转】Vue 2.0封装axios笔记
前言 单页面应用大多采用前后端分离开发思路,我们知道,前端和后端交互有多中方式(服务器端渲染.Ajax.websocket等),今天我们主要讲解Ajax部分. 最近团队讨论了一下,Ajax 本身跟 V ...