怒肝俩月,新鲜出炉史上最有趣的Java小白手册,第一版,每个 Java 初学者都应该收藏(16)

简介: 怒肝俩月,新鲜出炉史上最有趣的Java小白手册,第一版,每个 Java 初学者都应该收藏

02、枚举可用于 switch 语句


这个我在之前的一篇我去的文章中详细地说明过了,感兴趣的小伙伴可以点击链接跳转过去看一下。


switch (playerType) {
        case TENNIS:
            return "网球运动员费德勒";
        case FOOTBALL:
            return "足球运动员C罗";
        case BASKETBALL:
            return "篮球运动员詹姆斯";
        case UNKNOWN:
            throw new IllegalArgumentException("未知");
        default:
            throw new IllegalArgumentException(
                    "运动员类型: " + playerType);
    }


03、枚举可以有构造方法


如果枚举中需要包含更多信息的话,可以为其添加一些字段,比如下面示例中的 name,此时需要为枚举添加一个带参的构造方法,这样就可以在定义枚举时添加对应的名称了。


public enum PlayerType {
    TENNIS("网球"),
    FOOTBALL("足球"),
    BASKETBALL("篮球");
    private String name;
    PlayerType(String name) {
        this.name = name;
    }
}


04、EnumSet


EnumSet 是一个专门针对枚举类型的 Set 接口的实现类,它是处理枚举类型数据的一把利器,非常高效(内部实现是位向量,我也搞不懂)。


因为 EnumSet 是一个抽象类,所以创建 EnumSet 时不能使用 new 关键字。不过,EnumSet 提供了很多有用的静态工厂方法:


image.png


下面的示例中使用 noneOf() 创建了一个空的 PlayerType 的 EnumSet;使用 allOf() 创建了一个包含所有 PlayerType 的 EnumSet。


public class EnumSetTest {
    public enum PlayerType {
        TENNIS,
        FOOTBALL,
        BASKETBALL
    }
    public static void main(String[] args) {
        EnumSet<PlayerType> enumSetNone = EnumSet.noneOf(PlayerType.class);
        System.out.println(enumSetNone);
        EnumSet<PlayerType> enumSetAll = EnumSet.allOf(PlayerType.class);
        System.out.println(enumSetAll);
    }
}



程序输出结果如下所示:


[]

[TENNIS, FOOTBALL, BASKETBALL]


有了 EnumSet 后,就可以使用 Set 的一些方法了:


image.png


05、EnumMap


EnumMap 是一个专门针对枚举类型的 Map 接口的实现类,它可以将枚举常量作为键来使用。EnumMap 的效率比 HashMap 还要高,可以直接通过数组下标(枚举的 ordinal 值)访问到元素。


和 EnumSet 不同,EnumMap 不是一个抽象类,所以创建 EnumMap 时可以使用 new 关键字:


EnumMap<PlayerType, String> enumMap = new EnumMap<>(PlayerType.class);


有了 EnumMap 对象后就可以使用 Map 的一些方法了:



和 HashMap 的使用方法大致相同,来看下面的例子:


EnumMap<PlayerType, String> enumMap = new EnumMap<>(PlayerType.class);
enumMap.put(PlayerType.BASKETBALL,"篮球运动员");
enumMap.put(PlayerType.FOOTBALL,"足球运动员");
enumMap.put(PlayerType.TENNIS,"网球运动员");
System.out.println(enumMap);
System.out.println(enumMap.get(PlayerType.BASKETBALL));
System.out.println(enumMap.containsKey(PlayerType.BASKETBALL));
System.out.println(enumMap.remove(PlayerType.BASKETBALL));
1


程序输出结果如下所示:


{TENNIS=网球运动员, FOOTBALL=足球运动员, BASKETBALL=篮球运动员}

篮球运动员

true

篮球运动员


06、单例


通常情况下,实现一个单例并非易事,不信,来看下面这段代码


public class Singleton {  
    private volatile static Singleton singleton; 
    private Singleton (){}  
    public static Singleton getSingleton() {  
    if (singleton == null) {
        synchronized (Singleton.class) { 
        if (singleton == null) {  
            singleton = new Singleton(); 
        }  
        }  
    }  
    return singleton;  
    }  
}



但枚举的出现,让代码量减少到极致:


public enum EasySingleton{
    INSTANCE;
}


完事了,真的超级短,有没有?枚举默认实现了 Serializable 接口,因此 Java 虚拟机可以保证该类为单例,这与传统的实现方式不大相同。传统方式中,我们必须确保单例在反序列化期间不能创建任何新实例。


07、枚举可与数据库交互


我们可以配合 Mybatis 将数据库字段转换为枚举类型。现在假设有一个数据库字段 check_type 的类型如下:


`check_type` int(1) DEFAULT NULL COMMENT '检查类型(1:未通过、2:通过)',


它对应的枚举类型为 CheckType,代码如下:


public enum CheckType {
  NO_PASS(0, "未通过"), PASS(1, "通过");
  private int key;
  private String text;
  private CheckType(int key, String text) {
  this.key = key;
  this.text = text;
  }
  public int getKey() {
  return key;
  }
  public String getText() {
  return text;
  }
  private static HashMap<Integer,CheckType> map = new HashMap<Integer,CheckType>();
  static {
  for(CheckType d : CheckType.values()){
    map.put(d.key, d);
  }
  }
  public static CheckType parse(Integer index) {
  if(map.containsKey(index)){
    return map.get(index);
  }
  return null;
  }
}


1)CheckType 添加了构造方法,还有两个字段,key 为 int 型,text 为 String 型。


2)CheckType 中有一个public static CheckType parse(Integer index)方法,可将一个 Integer 通过 key 的匹配转化为枚举类型。


那么现在,我们可以在 Mybatis 的配置文件中使用 typeHandler 将数据库字段转化为枚举类型。


<resultMap id="CheckLog" type="com.entity.CheckLog">

<id property="id" column="id"/>

<result property="checkType" column="check_type" typeHandler="com.CheckTypeHandler"></result>

</resultMap>



其中 checkType 字段对应的类如下:


public class CheckLog implements Serializable {
    private String id;
    private CheckType checkType;
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public CheckType getCheckType() {
        return checkType;
    }
    public void setCheckType(CheckType checkType) {
        this.checkType = checkType;
    }
}


CheckTypeHandler 转换器的类源码如下:


public class CheckTypeHandler extends BaseTypeHandler<CheckType> {
  @Override
  public CheckType getNullableResult(ResultSet rs, String index) throws SQLException {
  return CheckType.parse(rs.getInt(index));
  }
  @Override
  public CheckType getNullableResult(ResultSet rs, int index) throws SQLException {
  return CheckType.parse(rs.getInt(index));
  }
  @Override
  public CheckType getNullableResult(CallableStatement cs, int index) throws SQLException {
  return CheckType.parse(cs.getInt(index));
  }
  @Override
  public void setNonNullParameter(PreparedStatement ps, int index, CheckType val, JdbcType arg3) throws SQLException {
  ps.setInt(index, val.getKey());
  }
}

CheckTypeHandler 的核心功能就是调用 CheckType 枚举类的 parse() 方法对数据库字段进行转换。

相关文章
|
5月前
|
设计模式 安全 Java
面向对象编程的精髓:Java设计模式 - 原型模式(Prototype)完全参考手册
【4月更文挑战第7天】原型模式是OOP中的创建型设计模式,用于通过复制现有实例创建新实例,尤其适用于创建成本高或依赖其他对象的情况。它包括Prototype接口、ConcretePrototype实现和Client客户端角色。优点是性能优化、避免子类化和动态增加产品族。实现包括定义原型接口、实现具体原型和客户端调用克隆方法。最佳实践涉及确保克隆正确性、选择深拷贝或浅拷贝及考虑线程安全。但需注意克隆方法管理、性能开销和循环引用等问题。在Java中,实现Cloneable接口和覆盖clone方法可实现原型模式。
62 4
|
5月前
|
网络协议 Java Maven
Java自救手册
Java自救手册
80 2
|
5月前
|
算法 Java
「译文」Java 垃圾收集参考手册(四):Serial GC
「译文」Java 垃圾收集参考手册(四):Serial GC
|
5月前
|
算法 Java PHP
「译文」Java 垃圾收集参考手册(一):垃圾收集简介
「译文」Java 垃圾收集参考手册(一):垃圾收集简介
|
4月前
|
Java 开发者
【技术成长日记】Java 线程的自我修养:从新手到大师的生命周期修炼手册!
【6月更文挑战第19天】Java线程之旅,从新手到大师的进阶之路:始于创建线程的懵懂,理解就绪与运行状态的成长,克服同步难题的进阶,至洞悉生命周期的精通。通过实例,展示线程的创建、运行与同步,展现技能的不断提升与升华。
33 2
|
4月前
|
Java 数据安全/隐私保护
Java基础手册二(类和对象 对象创建和使用 面向对象封装性 构造方法与参数传递 this关键字 static关键字 继承 多态 方法覆盖 final关键字 访问控制权限修饰符)
Java基础手册二(类和对象 对象创建和使用 面向对象封装性 构造方法与参数传递 this关键字 static关键字 继承 多态 方法覆盖 final关键字 访问控制权限修饰符)
31 0
|
4月前
|
存储 Java
Java基础手册(标识符 关键字 字面值 变量 数据类型 字符编码 运算符 控制语句 方法及方法重载和递归 面向对象与面向过程)
Java基础手册(标识符 关键字 字面值 变量 数据类型 字符编码 运算符 控制语句 方法及方法重载和递归 面向对象与面向过程)
31 0
|
4月前
|
存储 自然语言处理 Java
Java IO流完全手册:字节流和字符流的常见应用场景分析!
【6月更文挑战第26天】Java IO流涵盖字节流和字符流,字节流用于二进制文件读写及网络通信,如图片和音频处理;字符流适用于文本文件操作,支持多语言编码,确保文本正确性。在处理数据时,根据内容类型选择合适的流至关重要。
51 0
|
5月前
|
Java 开发者
效率工具RunFlow完全手册之Java开发者篇
这篇手册面向Java开发者,介绍了如何使用QLExpress执行Java代码和进行方法验证。示例包括数学计算、读取系统环境变量及格式化输出。QLExpress提供运行时执行Java代码的功能,并支持QLExpress语法的脚本文件。
40 3
效率工具RunFlow完全手册之Java开发者篇
|
5月前
|
算法 安全 Java
「译文」Java 垃圾收集参考手册(三):GC 算法基础篇
「译文」Java 垃圾收集参考手册(三):GC 算法基础篇
下一篇
无影云桌面