Java 碎片化知识点

发布于 2023-08-25

获取当前时间戳

import java.time.Instant;

//10位时间戳, 1692893144
long epochSecond = Instant.now().getEpochSecond();
//10位时间戳, 整型, 1692893144
int epochSecond1 = (int) Instant.now().getEpochSecond();
//13位时间戳, 1692893144845
long epochMilli = Instant.now().toEpochMilli();
//13位时间戳, 1692893144845
long currentTimeMillis = System.currentTimeMillis();

时间戳转 LocalDateTime

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;

LocalDateTime localDateTime = Instant.ofEpochSecond(1692893364).atZone(ZoneId.systemDefault()).toLocalDateTime();
LocalDateTime localDateTime1 = LocalDateTime.ofInstant(Instant.ofEpochSecond(1692893364), ZoneId.systemDefault());
LocalDateTime localDateTime2 = Instant.ofEpochMilli(1692893364596L).atZone(ZoneId.systemDefault()).toLocalDateTime();
LocalDateTime localDateTime3 = LocalDateTime.ofInstant(Instant.ofEpochMilli(1692893364596L), ZoneId.systemDefault());

格式化 LocalDateTime

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

//2023-08-25 00:20:53
//java8 推荐使用 DateTimeFormatter 来格式化
String format = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));

枚举类之间的相互依赖问题

场景是,目前项目中已经有一个书籍的枚举类 BookEnum (此处为代指),现在有新的需求需要为书籍增加分类。 最简单的做法是在 BookEnum 中新增一个 private String category 字段来表示类别。 但这样存在的问题是:

  1. 分类都是字符串,同一个分类需要重复定义
  2. 后续如果继续还要给书籍增加属性,还要继续扩展这个 BookEnum 枚举类,会造成越来越臃肿

基于上述 2 点,现考虑新增一个表示类别的枚举类 CategoryEnum 。 书籍和分类的关系维护在 CategoryEnum 枚举类中。 同时 需要保证每本书都要定义所属类别,且, 有且只能有一个类别

具体代码实现如下:

public class Main {
    public static void main(String[] args) {
        System.out.println("Main方法--开始");
        System.out.println("BookEnum.B1是否定义了归属类别: " + CategoryEnum.defined(BookEnum.B1));
        System.out.println("Main方法--结束");
    }
}
public enum BookEnum {

    B1("Book1"),
    B2("Book2"),
    ;

    private final String code;
    private final String desc;

    static {
        System.out.println("BookEnum 静态代码块--开始");
        System.out.println("BookEnum 静态代码块--结束");
    }

    BookEnum(String desc) {
        this.code = name();
        this.desc = desc;
        System.out.println("BookEnum 构造函数" + code);
    }

    public String getCode() {
        return code;
    }

    public String getDesc() {
        return desc;
    }
}
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

public enum CategoryEnum {

    C1("CAT1", Arrays.asList(BookEnum.B1)),
    C2("CAT2", Arrays.asList(BookEnum.B2)), //如果注释掉该行代码, 会因为BookEnum.B2没有定义所属Category而抛出异常
    //C3("CAT3", Arrays.asList(BookEnum.B2)), //如果打开该行注释, 会因为BookEnum.B2同时归属于两个Category而抛出异常
    ;

    private final String code;
    private final String desc;
    private final Set<BookEnum> types;

    private static final Map<BookEnum, CategoryEnum> BOOK_CATEGORY_MAPPING = new ConcurrentHashMap<>();

    static {
        System.out.println("CategoryEnum 静态代码块--开始");
        initializeBookCategoryMap();
        System.out.println("CategoryEnum 静态代码块--结束");
    }

    private static void initializeBookCategoryMap() {
        for (CategoryEnum category : CategoryEnum.values()) {
            for (BookEnum book : category.getTypes()) {
                if (defined(book)) {
                    throw new RuntimeException("重复定义所属类别: " + book.getCode());
                }
                BOOK_CATEGORY_MAPPING.put(book, category);
            }
        }

        for (BookEnum book : BookEnum.values()) {
            if (!defined(book)) {
                throw new RuntimeException("未定义所属类别:" + book.getCode());
            }
        }
    }

    CategoryEnum(String desc, List<BookEnum> types) {
        this.code = name();
        this.desc = desc;
        this.types = new HashSet<>(types);
        System.out.println("CategoryEnum 构造函数" + code);
    }

    public String getCode() {
        return code;
    }

    public String getDesc() {
        return desc;
    }

    public Set<BookEnum> getTypes() {
        return types;
    }

    public static boolean defined(BookEnum bookEnum) {
        return BOOK_CATEGORY_MAPPING.containsKey(bookEnum);
    }
}

执行 Main 方法的输出为:

Main方法--开始
BookEnum 构造函数B1
BookEnum 构造函数B2
BookEnum 静态代码块--开始
BookEnum 静态代码块--结束
CategoryEnum 构造函数C1
CategoryEnum 构造函数C2
CategoryEnum 静态代码块--开始
CategoryEnum 静态代码块--结束
BookEnum.B1是否定义了归属类别: true
Main方法--结束