求一个java算法,java 枚举类型法除外.

让天下没有难学的技术
Java秘术:用枚举构建一个状态机
Java秘术:用枚举构建一个状态机
作者:Peter Lawrey
译者:陈振阳
Java中的enum比其他的语言中的都强大,这产生了很多令人惊讶的用法。本文中,我将列出Java中的enum的一些特性,然后将这些特性应用到一起构成一个状态机。
Enum的单例和工具类用法
你可以非常简单地用一个enum构建一个单例或者工具类。
enum Singleton {
enum Utility {
// no instances
用enum实现一个接口
你也可以在一个enum中实现一个接口。
interface Named {
public String name();
public int order();
enum Planets implements Named {
Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, N
// name() is implemented automagically.
public int order() { return ordinal()+1; }
每一个enum实例,一个不同的子类
你可以重载一个enum实例的方法。这将高效的给一个enum的实例一个自己的实现。
// from /javase/1,5.0/docs/guide/language/enums.html
public enum Operation {
{ double eval(double x, double y) { return x + } },
{ double eval(double x, double y) { return x - } },
{ double eval(double x, double y) { return x * } },
DIVIDE { double eval(double x, double y) { return x / } };
// Do arithmetic op represented by this constant
abstract double eval(double x, double y);
使用一个enum实现一个状态机
用上边的技术,你可以做的是创建一个基于状态的enum。
在这个小例子中,解析器的状态机处理一个ByteBuffer里的原始的XML。每一个状态都有自己的处理方法,如果没有足够的可用的数据,状态机可以回来再次获取更多的数据。状态之间的每一次变换都被定义,所有状态的代码在一个enum中。
interface Context {
ByteBuffer buffer();
State state();
void state(State state);
interface State {
* @return true to keep processing, false to read more data.
boolean process(Context context);
enum States implements State {
public boolean process(Context context) {
if (context.buffer().remaining() & 16)
// read header
if(headerComplete)
context.state(States.ROOT);
public boolean process(Context context) {
if (context.buffer().remaining() & 8)
// read root tag
if(rootComplete)
context.state(States.IN_ROOT);
public void process(Context context) {
socket.read(context.buffer());
while(context.state().process(context));
使用这种方式,可以创建一个XML解析器,解析器可以在10微秒内处理完数据包。大多数情况下,它跟你需要的一样高效。
Reference:
原创文章,转载请注明: 转载自本文链接地址:
Latest posts by 陈振阳 ()
Related posts:
(2 votes, average: 5.00 out of 5)
Loading...java(21)
& & & & java 提供了两个枚举集合:EnumSet和EnumMap,这两个集合的使用都比较简单,EnumSet表示其元素必须是某一枚举的枚举项,EnumMap表示Key值必须是某一枚举的枚举项,由于枚举类的实例数量固定并且有限,相对来说EnumSet和EnumMap的效率会比其他Set和Map要高。
为什么要限定在64个枚举项以内?
虽然EnumSet很好用,但是它有一个隐藏的特点,看源代码:
& & &* Creates an enum set containing all of the elements in the specified
& & &* element type.
& & &* @param elementType the class object of the element type for this enum
& & &* & & set
& & &* @throws NullPointerException if &tt&elementType&/tt& is null
& & public static &E extends Enum&E&& EnumSet&E& allOf(Class&E& elementType) {
& & & & EnumSet&E& result =&noneOf(elementType);
& & & & result.addAll();
& &&allOf通过nonof方法首先生产一个EnumSet对象,然后把所有的枚举项都加进去。&&&&
& & &* Creates an empty enum set with the specified element type.
& & &* @param elementType the class object of the element type for this enum
& & &* & & set
& & &* @throws NullPointerException if &tt&elementType&/tt& is null
& & public static &E extends Enum&E&& EnumSet&E& noneOf(Class&E& elementType) {
&&&&& & //获得所有枚举项
& & & & Enum[] universe = getUniverse(elementType);
& & & & if (universe == null)
& & & & & & throw new ClassCastException(elementType + & not an enum&);
& & & & if (universe.length &= 64)
&&&&&&&&& & //枚举数量小于等于64
& & & & & & return new RegularEnumSet&E&(elementType, universe);
& & & & else
&&&&&&&&& &&//枚举数量大于64
& & & & & & return new JumboEnumSet&E&(elementType, universe);
RegularEnumSet 实例对象
class RegularEnumSet&E extends Enum&E&& extends EnumSet&E& {
& & &* Bit vector representation of this set. &The 2^k bit indicates the
& & &* presence of universe[k] in this set.
& & //记录所有枚举排序号,注意是Long型
& & private long elements = 0L;
& & //构造函数
& & RegularEnumSet(Class&E&elementType, Enum[] universe) {
& & & & super(elementType, universe);
& & void addRange(E from, E to) {
& & & & elements = (-1L &&& &(from.ordinal() - to.ordinal() - 1)) && from.ordinal();
& & //加入所有元素
& & void addAll() {
& & & & if (universe.length != 0)
& & & & & & elements = -1L &&& -universe.
JumboEnumSet实例对象
class JumboEnumSet&E extends Enum&E&& extends EnumSet&E& {
& & &* Bit vector representation of this set. &The ith bit of the jth
& & &* element of this array represents the &presence of universe[64*j +i]
& & &* in this set.
& & //映射所有的枚举项
& & private long elements[];
& & // Redundant - maintained for performance
& & private int size = 0;
& & //构造函数
& & JumboEnumSet(Class&E&elementType, Enum[] universe) {
& & & & super(elementType, universe);
& & & & elements = new long[(universe.length + 63) &&& 6];
& & void addRange(E from, E to) {
& & & & int fromIndex = from.ordinal() &&& 6;
& & & & int toIndex = to.ordinal() &&& 6;
& & & & if (fromIndex == toIndex) {
& & & & & & elements[fromIndex] = (-1L &&& &(from.ordinal() - to.ordinal() - 1))
& & & & & & & & & & & & & & && from.ordinal();
& & & & } else {
& & & & & & elements[fromIndex] = (-1L && from.ordinal());
& & & & & & for (int i = fromIndex + 1; i & toI i++)
& & & & & & & & elements[i] = -1;
& & & & & & elements[toIndex] = -1L &&& (63 - to.ordinal());
& & & & size = to.ordinal() - from.ordinal() + 1;
& & void addAll() {
& &&& &&//elements 中每个元素表示64个枚举项
&&&&& & for (int i = 0; i & elements. i++)
& & &&&&& & & & elements[i] = -1;
& & & & &&&&&&&&elements[elements.length - 1] &&&= -universe.
& & & & &&&&&&&&size = universe.
&&&&&&&&从以上的源码分析可以看出,EnumSet提供的两个实现类都是基本的数字类型操作,其性能肯定比其他的Set类型要好很多,特别是Enum的数量少于64的时候,那简直就是飞一般的速度。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:150295次
积分:2443
积分:2443
排名:第9966名
原创:117篇
评论:15条
(3)(3)(5)(24)(66)(4)(1)(1)(2)(1)(1)(2)(5)Java枚举详解及使用实例(涵盖了所有典型用法)
投稿:junjie
字体:[ ] 类型:转载 时间:
这篇文章主要介绍了Java枚举详解及使用实例(涵盖了所有典型用法),本文直接给出实例代码,代码中包含详细注释,需要的朋友可以参考下
在实际编程中,往往存在着这样的“数据集”,它们的数值在程序中是稳定的,而且“数据集”中的元素是有限的。
例如星期一到星期日七个数据元素组成了一周的“数据集”,春夏秋冬四个数据元素组成了四季的“数据集”。
在java中如何更好的使用这些“数据集”呢?因此枚举便派上了用场,以下代码详细介绍了枚举的用法。
package com.ljq.
* 枚举用法详解
* @author jiqinlin
public class TestEnum {
* 普通枚举
* @author jiqinlin
public enum ColorEnum {
red, green, yellow,
* 枚举像普通的类一样可以添加属性和方法,可以为它添加静态和非静态的属性或方法
* @author jiqinlin
public enum SeasonEnum {
//注:枚举写在最前面,否则编译出错
spring, summer, autumn,
private final static String position = "test";
public static SeasonEnum getSeason() {
if ("test".equals(position))
* 实现带有构造器的枚举
* @author jiqinlin
public enum Gender{
//通过括号赋值,而且必须带有一个参构造器和一个属性跟方法,否则编译出错
//赋值必须都赋值或都不赋值,不能一部分赋值一部分不赋值;如果不赋值则不能写构造器,赋值编译也出错
MAN("MAN"), WOMEN("WOMEN");
private final S
//构造器默认也只能是private, 从而保证构造函数只能在内部使用
Gender(String value) {
this.value =
public String getValue() {
* 订单状态
* 实现带有抽象方法的枚举
* @author jiqinlin
public enum OrderState {
/** 已取消 */
CANCEL {public String getName(){return "已取消";}},
/** 待审核 */
WAITCONFIRM {public String getName(){return "待审核";}},
/** 等待付款 */
WAITPAYMENT {public String getName(){return "等待付款";}},
/** 正在配货 */
ADMEASUREPRODUCT {public String getName(){return "正在配货";}},
/** 等待发货 */
WAITDELIVER {public String getName(){return "等待发货";}},
/** 已发货 */
DELIVERED {public String getName(){return "已发货";}},
/** 已收货 */
RECEIVED {public String getName(){return "已收货";}};
public abstract String getName();
public static void main(String[] args) {
//枚举是一种类型,用于定义变量,以限制变量的赋值;赋值时通过“枚举名.值”取得枚举中的值
ColorEnum colorEnum = ColorEnum.
switch (colorEnum) {
System.out.println("color is red");
case green:
System.out.println("color is green");
case yellow:
System.out.println("color is yellow");
case blue:
System.out.println("color is blue");
//遍历枚举
System.out.println("遍历ColorEnum枚举中的值");
for(ColorEnum color : ColorEnum.values()){
System.out.println(color);
//获取枚举的个数
System.out.println("ColorEnum枚举中的值有"+ColorEnum.values().length+"个");
//获取枚举的索引位置,默认从0开始
System.out.println(ColorEnum.red.ordinal());//0
System.out.println(ColorEnum.green.ordinal());//1
System.out.println(ColorEnum.yellow.ordinal());//2
System.out.println(ColorEnum.blue.ordinal());//3
//枚举默认实现了parable接口
System.out.println(pareTo(ColorEnum.green));//-1
//--------------------------
System.out.println("===========");
System.err.println("季节为" + SeasonEnum.getSeason());
//--------------
System.out.println("===========");
for(Gender gender : Gender.values()){
System.out.println(gender.value);
//--------------
System.out.println("===========");
for(OrderState order : OrderState.values()){
System.out.println(order.getName());
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具JAVA枚举可以用来做什么?举一个简单的例子(用枚举、不用)_百度知道
JAVA枚举可以用来做什么?举一个简单的例子(用枚举、不用)
提问者采纳
唯一要注意的只是变量和方法定义必须放在所有枚举值定义的后面。前面我们看到可以为enum定义一些方法,Blue{public String toString(){ return &quot: return Color。 public enum Color { Red(&quot,这些变量可以用任何你想用的修饰符.desc,个人觉得一般也不需要过多的使用enum的一些高级特性。总的来说,是希望能够帮助程序员写出的代码更加简单易懂:” + c).toString()默认返回字符串”Blue”.Red&quot.Blue&quot, Blue(&quot: return &quot。3.覆载(Override)toS default.Red。3.Enum默认实现了java,因此我们如果调用C }
}这里我们为每一个颜色提供了一个说明信息public enum Color {Red { public String toString(){ return &quot。前面我们已经知道enum提供了toString.public String toString(){ switch (this){ case Red.println(“find value.RThis is Red&quot。调用valueOf(“Blue”)将返回Color,enum作为一个全新定义的类型.可以看到toString确实是被覆载了;, Green,我们可以轻车熟路地用ForEach循环来遍历了枚举值了,因为我们知道枚举值是public static final的常量而已; } }: return &,valueOf等方法;C2.在enum中定义方法和变量.Red。这也是完全符合情理的.G case Blue. } }: return Color。一般来说在覆载toString的时候我们同时也应该覆载valueOf方法; case 2。其实这和覆载一个普通class的toString方法没有什么区别.desc = desc.因此我们在自己重写toString方法的时候就要注意到这一点.Blue而不是RedGreenparable接口。4.使用构造函数. 知道了有values方法。当我们在声明一个enum类型时.Blue, Green(&quot。这样,这个方法使你能够方便的遍历所有的枚举值;);
},我们可以和在普通类里面定义变量一样定义其它任何类型的非枚举变量。6.定义枚举值自己的方法。要注意这里构造函数不能为public或者protected: return &quot。虽然enum不可以有public的构造函数,其实我们甚至可以为每一个枚举值定义方法.ordinal()返回0: return C case Green,以保持它们相互的一致性。从逻辑上来说这样比原先提供一个“全局“的toString方法要清晰一些;This is Blue&quot. private static int number = Color.out,否则就和简单易懂的初衷想违背了。 1.遍历所有有枚举值,这个方法和toString方法是相对应的.Blue&quot,在enum内部使用.Blue,这里就不作示例了,它要实现一个接口也和普通class实现一个接口一样。for (Color c。4.Enum覆载了了toString方法。7.Enum还有一个oridinal的方法。6.Enum还提供了values方法,这个方法返回枚举值在枚举类种的顺序.Green&quot,我们前面覆载 toString的例子可以被改写成这样,否则编译器会给出一个错误, Blue.values();
} } …,Green {public String toString(){ return &quot,我们应该注意到enum类型有如下的一些特征, 然后定义了一个构造函数接受这个说明信息;CColor。2.所有枚举值都是Unknow Color&quot。 public enum Color { Red,客户代码不能new一个枚举值的实例出来; case 1: CColor.values())S; default ,这个顺序根据枚举值声明的顺序而定;
private String desc: return Color。 …。1.它不能有public的构造函数, 从而保证构造函数只能在内部使用;This is Green&quot.这时我们可以看到.Red&).currentTimeMillis() % }
},比如我们可以为Color增加一个方法随机返回一个颜色.Blue,这样做可以保证客户代码没有办法新建一个enum的实例;C.GreenC,此时再用前面的遍历代码打印出来的是Color。注意这一点只是针对于枚举值;,很多时候我们都需要覆载默认的toString方法,那么对于enum我们怎么做呢;): return &quot。5.实现特定的接口我们已经知道enum可以定义变量和方法; } public String getDesc(){ return this,switch ((int) random){ case 0; Color(String desc){ this.RedCColor.5.Enum提供了一个valueOf方法, final的。还是用Color这个例子,看起来很象是特殊的class,可以定义自己的方法,但是我们还是可以定义private的构造函数Enum作为Sun全新引进的一个关键字;public static Color getRandomColor(){ long random = System, 它也可以有自己的变量; }
} }可以看出这在枚举类型里定义变量和方法和在普通类里面定义方法和变量没有什么区别, valueOf方法.Green&quot,一把来说应该相对应地重写valueOf方法,可以实现一个或者多个接口;,这里Color
提问者评价
听得头疼。好难。。不过谢谢
来自团队:
其他类似问题
枚举名。只能使用这几个属性.方向相当于定义了一个规范吧。然后调用的时候直接,一个程序里就用到了4个方向。你就可以把方向定义成枚举。上下左右比如
为您推荐:
其他3条回答
枚举也是个类,也可能不安全但运用枚举,规范简洁,常量不可以用switch ,还可以有自己的逻辑处理,枚举还可以把一类相似的 表示 归结到同一个枚举中:枚举可以限定取值范围.比如性别,而枚举可以,但可能要做更多的工作。简单说,其他值都是不合法的如果不用枚举也可以构造这样的方法,所有的内容只能从指定范围中取得,只有男和女我理解为:枚举可以取代原来用final定义常量的方式
其实枚举最大的作用是是用来规范语言,增加代码的整洁程度及便于阅读。这个非常重要。介绍一本《整洁代码》,可以多看看。
举个最简单的 常量public enum Color {
RED, GREEN, BLANK, YELLOW
枚举的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁java 怎样限制一个函数允许传入的值仅为枚举类型的?_百度知道
java 怎样限制一个函数允许传入的值仅为枚举类型的?
java 定义一个方法,怎样要求使用者入参必须为枚举类型
提问者采纳
&&nbsp,RED;&&public&&&&&&public&&&color){&&printColor(Color&&&static&&Color{&&&nbsp,BLUE}public&//这样写就限制了传入的参数必须为枚举&&&class&void&&&&&static&&&&&printColor(C&&&}&enum&void&&main(String&&nbsp//定义一个枚举&System.name());_Test{&&&&args[]){&nbsp.GREEN);&&GREEN.println(&&&nbsp.out
提问者评价
搞定了,TKS
来自团队:
其他类似问题
为您推荐:
其他2条回答
哈哈,你定义这个方法的参数为枚举类型,不就限制了在调用时必须传入枚举类型数据了吗
例如public void method(Object&? extends enum& obj) {}
枚举类型的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁}

我要回帖

更多关于 java 枚举类型 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信