ИМХО, я сомневаюсь, что вы не используете перечисления Java

Java

Перейдем сразу к делу, enum (перечисление) — это ключевое слово, введенное в Java 1.5, оно представляет особый тип класса, используемый по умолчанию.наследоватьИз java.lang.Enum.

Чтобы продемонстрировать это, давайте создадим новое перечисление PlayerType:

public enum PlayerType {
    TENNIS,
    FOOTBALL,
    BASKETBALL
}

Имя класса с двумя ключевыми словами, а также брекетами, а также три заглавные слова, но не видели наследовать enum класс ах? Не волнуйтесь, ешьте горячий тофу ах. Используйте JAD Посмотрите на код байтового кода, четкое изображение.

public final class PlayerType extends Enum
{

    public static PlayerType[] values()
    {
        return (PlayerType[])$VALUES.clone();
    }

    public static PlayerType valueOf(String name)
    {
        return (PlayerType)Enum.valueOf(com/cmower/baeldung/enum1/PlayerType, name);
    }

    private PlayerType(String s, int i)
    {
        super(s, i);
    }

    public static final PlayerType TENNIS;
    public static final PlayerType FOOTBALL;
    public static final PlayerType BASKETBALL;
    private static final PlayerType $VALUES[];

    static 
    {
        TENNIS = new PlayerType("TENNIS", 0);
        FOOTBALL = new PlayerType("FOOTBALL", 1);
        BASKETBALL = new PlayerType("BASKETBALL", 2);
        $VALUES = (new PlayerType[] {
            TENNIS, FOOTBALL, BASKETBALL
        });
    }
}

Ты видел? Класс PlayerType является окончательным и наследуется от класса Enum. Мы, программисты, не делали эти задачи, компилятор спокойно делал это за нас. Кроме того, он поставляется с несколькими полезными статическими методами, такими какvalues()иvalueOf(String name).

01. Внутреннее перечисление

Хорошо, ребята, вы уже должны знать, как выглядит перечисление, верно? Поскольку перечисление — это особый класс, его можно определить внутри класса, так что его область действия может быть ограничена внешним классом.

public class Player {
    private PlayerType type;
    public enum PlayerType {
        TENNIS,
        FOOTBALL,
        BASKETBALL
    }
    
    public boolean isBasketballPlayer() {
      return getType() == PlayerType.BASKETBALL;
    }

    public PlayerType getType() {
        return type;
    }

    public void setType(PlayerType type) {
        this.type = type;
    }
}

PlayerType эквивалентен внутреннему классу Player,isBasketballPlayer()Метод используется для определения того, является ли спортсмен баскетболистом.

Поскольку перечисление является окончательным, его можно гарантировать, что в виртуальной машине Java есть только один постоянный объект (см.статический блок кода«часть кода, где ключевое слово static заключено в фигурные скобки»), поэтому мы можем безопасно использовать оператор «==» для сравнения двух перечислений на равенство, см.isBasketballPlayer()метод.

тогда почему бы не использоватьequals()суждение о методе?

if(player.getType().equals(Player.PlayerType.BASKETBALL)){};
if(player.getType() == Player.PlayerType.BASKETBALL){};

Когда оператор «==» сравнивает, если оба объекта нулевые, это не происходитNullPointerExceptionequals()метод будет.

Кроме того, во время компиляции будет проверяться оператор "==", и если типы с обеих сторон не совпадают, будет выдано сообщение об ошибке, аequals()метод нет.

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. У перечислений могут быть конструкторы

Если перечисление должно содержать больше информации, вы можете добавить в него некоторые поля, такие как имя в следующем примере.В этом случае вам нужно добавить конструктор с параметрами в перечисление, чтобы вы могли добавить соответствующие параметры при определении перечисления.имя.

public enum PlayerType {
    TENNIS("网球"),
    FOOTBALL("足球"),
    BASKETBALL("篮球");

    private String name;

    PlayerType(String name) {
        this.name = name;
    }
}

04. Набор перечислений

EnumSet — это класс реализации, предназначенный для интерфейса Set типов перечисления, это мощный инструмент для обработки данных типа перечисления и очень эффективный (внутренняя реализация — это битовый вектор, и я этого не понимаю).

Поскольку EnumSet является абстрактным классом, ключевое слово new нельзя использовать при создании EnumSet. Однако EnumSet предоставляет множество полезных статических фабричных методов:

В следующем примере используетсяnoneOf()Создан наложение пустых Playertypes; использоватьallOf()Создается 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:

05. Карта перечисления

EnumMap — это класс реализации интерфейса Map специально для типов перечисления, который может использовать константы перечисления в качестве ключей. EnumMap даже более эффективен, чем HashMap, и доступ к элементам можно получить напрямую через индексы массива (порядковые значения перечисления).

В отличие от EnumSet, EnumMap не является абстрактным классом, поэтому вы можете использовать новое ключевое слово при создании EnumMap:

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));

Вывод программы следующий:

{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;
}

Это закончено, это действительно супер коротко, не так ли? Перечисление реализует сериализуемый интерфейс по умолчанию, поэтому виртуальная машина Java может гарантировать, что класс является Singleton, который не совпадает с традиционной реализацией. Традиционно мы должны были обеспечить, чтобы Синглтон не мог создать какие-либо новые экземпляры во время десериализации.

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 добавляет конструктор и два поля, ключ типа int и текст типа String.

2) Есть один в CheckTypepublic static CheckType parse(Integer index)метод, который может преобразовать Integer в тип перечисления путем сопоставления ключа.

Итак, теперь мы можем использовать в файле конфигурации MybatistypeHandlerПреобразование полей базы данных в типы перечисления.

<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()метод преобразования полей базы данных.

ИМХО, после прочтения этой статьи, я думаю, что мои друзья точно будут использовать Java-перечисление, если нет, то приходите и режьте меня!

Если вы считаете, что ваша статья немного поможет, поищите в WeChat »Тихий король 2"Прочитал в первый раз, ответь"параллелизмСуществует также практика параллельного программирования на Java, переписанная Али Даниэлем, и вам больше не придется беспокоиться о трудностях интервьюера в этом отношении.

Эта статья была включена в GitHub,Портал~, а также полноценные тестовые сайты для интервью с крупными производителями Добро пожаловать в Star.

Я Тихий Король Эр, программист с красивой внешностью, но полагающийся на талант.Подпишитесь, чтобы повысить эффективность обучения, не забудьте утроить, лайкнуть, добавить в избранное, оставить сообщение, я не выбираю, хи-хи.