Понимание перечислений в Java

Здесь вы можете использовать interaction:

A <- data.frame(Col1=1:3, Col2=2:4, Col3=10:12)
B <- data.frame(Col1=1:2, Col2=2:3, Col3=10:11)
A
#  Col1 Col2 Col3
#1    1    2   10
#2    2    3   11
#3    3    4   12

B
# Col1 Col2 Col3
#1    1    2   10
#2    2    3   11

byv <- c("Col1","Col2")
A[!(interaction(A[byv]) %in% interaction(B[byv])),]

#  Col1 Col2 Col3
#3    3    4   12

Или создать уникальный идентификатор для каждой строки, а затем исключить те, которые были объединены:

A[-merge(cbind(A[byv],id=seq_len(nrow(A))), B[byv], by=byv)$id,]
16
задан cletus 19 September 2009 в 18:55
поделиться

6 ответов

Перечисления в Java 5+ - это в основном классы, которые имеют предопределенный набор экземпляров. Они предназначены для замены, скажем, набора целочисленных констант. Предпочтительнее использовать константы, поскольку они могут обеспечить безопасность типов.

Итак, вместо:

public class Suit {
  public final static int SPADES = 1;
  public final static int CLUBS = 2
  public final static int HEARTS = 3;
  public final static int DIAMONDS = 4;
}

у вас есть:

public enum Suit {
  SPADES, CLUBS, HEARTS, DIAMONDS
}

Преимущества:

  1. Безопасность типов. Вы можете объявить аргумент функции, тип возвращаемого значения, член класса или локальную переменную как определенный тип Enum, и компилятор будет обеспечивать безопасность типов;
  2. Перечисления - это в основном классы. Они могут реализовывать интерфейсы, иметь поведение и т. Д.

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

int i = Suit.DIAMONDS * Suit.CLUBS;

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

Вы можете использовать класс для Suit для обеспечения безопасности типов, и это было решение до Java 5. Джош Блох (в Эффективная Java , который должен прочитать для программистов Java imho) продвинул шаблон перечисления типов, который стал перечислением Java 5+. В нем есть изрядное количество шаблонов и некоторые угловые случаи, которые люди не склонны обслуживать, например, сериализация без вызова конструктора и обеспечение только одного экземпляра, который необходимо переопределить для метода readResolve ().

Например:

public enum CardColour {
  RED, BLACK
}

public enum Suit {
  SPADES(CardColour.BLACK),
  CLUBS(CardColour.BLACK),
  HEARTS(CardColour.RED),
  DIAMONDS(CardColour.RED);

  private final CardColour colour;

  Suit(CardColour colour) { this.colour = colour; }

  public CardColour getColour() { return colour; }
}

Редактировать: Sun имеет введение в типы безопасных перечислений .

Что касается интерфейсов, они действительно дополняют перечисления, а не являются альтернативой. Как вы могли бы сказать, что Suit - это интерфейс, и у вас будет следующее:

public interface Suit {
  CardColour getColour();
}

Проблема в том, что вы можете определить 300 различных мастей, а также несколько раз определить пик. Еще одно преимущество перечислений (несмотря на угловые случаи загрузки классов) заключается в том, что существует только один экземпляр каждого значения перечисления. Обычно это называется имеющим каноническое значение , что означает, что это равенство выполняется:

a.equals(b) == b.equals(a) == (a == b)

для всех a, b, которые являются экземплярами определенного Enum. Это означает, что вместо записи:

if (card.getSuit().equals(Suit.SPADES)) { ... }

вы можете написать:

if (card.getSuit() == Suit.SPADES) { ... }

, что быстрее и обычно легче читается. Кроме того, IDE обычно дают вам обратную связь, если вы сравниваете перечисления разных типов, говоря, что они не могут быть равными, что может быть полезной и ранней формой проверки ошибок.

Еще одно преимущество перечислений (несмотря на угловые случаи загрузки классов) заключается в том, что существует только один экземпляр каждого значения перечисления. Обычно это называется имеющим каноническое значение , что означает, что это равенство выполняется:

a.equals(b) == b.equals(a) == (a == b)

для всех a, b, которые являются экземплярами определенного Enum. Это означает, что вместо записи:

if (card.getSuit().equals(Suit.SPADES)) { ... }

вы можете написать:

if (card.getSuit() == Suit.SPADES) { ... }

, что быстрее и обычно легче читается. Кроме того, IDE обычно дают вам обратную связь, если вы сравниваете перечисления разных типов, говоря, что они не могут быть равными, что может быть полезной и ранней формой проверки ошибок.

Еще одно преимущество перечислений (несмотря на угловые случаи загрузки классов) заключается в том, что существует только один экземпляр каждого значения перечисления. Обычно это называется имеющим каноническое значение , что означает, что это равенство выполняется:

a.equals(b) == b.equals(a) == (a == b)

для всех a, b, которые являются экземплярами определенного Enum. Это означает, что вместо записи:

if (card.getSuit().equals(Suit.SPADES)) { ... }

вы можете написать:

if (card.getSuit() == Suit.SPADES) { ... }

, что быстрее и легче для чтения. Кроме того, IDE обычно дают вам обратную связь, если вы сравниваете перечисления разных типов, говоря, что они не могут быть равными, что может быть полезной и ранней формой проверки ошибок.

if (card.getSuit() == Suit.SPADES) { ... }

, который быстрее и легче читается. Кроме того, IDE обычно дают вам обратную связь, если вы сравниваете перечисления разных типов, говоря, что они не могут быть равными, что может быть полезной и ранней формой проверки ошибок.

if (card.getSuit() == Suit.SPADES) { ... }

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

49
ответ дан 30 November 2019 в 10:07
поделиться

Перечисление Java является специальным типом Java, используемым для определения наборы констант . Более точно тип перечисления Java является специальным видом класса Java. Перечисление может содержать константы, методы и т.д. Перечисления Java были добавлены в Java 5.

public enum Level {
    HIGH,
    MEDIUM,
    LOW
}

Байт-код:

public final enum package/Level extends java/lang/Enum  {

  // compiled from: Level.java

  public final static enum package/Level; HIGH
  public final static enum package/Level; MEDIUM
  public final static enum package/Level; LOW

  //...
}

перечисления Java расширяют java.lang. Класс Enum неявно, таким образом, Ваши перечислимые типы не могут расширить другой класс.

, Если перечисление Java содержит поля и методы, определение полей и методы должны всегда появляться после списка констант в перечислении. Кроме того, список перечислимых констант должен быть завершен точкой с запятой ;

EnumSet - Java содержит специальную реализацию Набора Java под названием EnumSet, который может содержать перечисления более эффективно, чем стандартные реализации Набора Java. <глоток> [О]

EnumMap - Java также содержит специальную Реализацию Map Java, которая может использовать экземпляры перечисления Java в качестве ключей. <глоток> [EnumMap по сравнению с HashMap]

чиновник Android документ

Избегает перечислений
А, единственное перечисление может добавить приблизительно 1,0 к 1,4 КБ размера в classes.dex файл Вашего приложения. Эти дополнения могут быстро накопиться для сложных систем или совместно использованных библиотек. Если возможно, рассмотрите использование @IntDef аннотации и ProGuard, чтобы разделить перечисления и преобразовать их в целые числа. Это преобразование типов сохраняет все преимущества безопасности типов перечислений.

Read больше здесь , здесь , здесь

0
ответ дан 28 September 2019 в 22:17
поделиться

Документация Sun enum , вероятно, является лучшим объяснением. Конечно, вы можете обойтись и без них, как, конечно же, делали Java-программисты до выхода Java 1.5. Обычно то же самое можно сделать, используя константы в версиях Java до 1.5. Но перечисления очень удобны.

1
ответ дан 30 November 2019 в 10:07
поделиться

Если ситуация не возникает, тогда они вам не нужны.

Они позволяют вам иметь четко определенный набор вещей, например, если вы хотите представить состояния из того, что вы могли бы иметь:

enum MatterState {
    Solid,
    Liquid,
    Gas;
}

Где они превзошли старый стиль использования объектов для представления наборов несколькими способами, некоторые из которых:

  • Вы можете использовать их в переключателе заявления.
  • Меньше кода.
  • Встроенный в / из строки.
1
ответ дан 30 November 2019 в 10:07
поделиться

Думайте о Enum следующим образом

public class MyEnum {

    // Object instantiated at declaration
    public static final MyEnum ONE = new MyEnum();
    public static final MyEnum TWO = new MyEnum();
    public static final MyEnum THREE = new MyEnum();

    // Notice a private constructor 
    // There is no way outside MyEnum class call it
    private MyEnum() { ... }


}

Итак, MyEnum в качестве перечисления будет

public enum MyEnum {
    ONE,
    TWO,
    THREE;
}

Оба аналогичны

в отношении,

18
ответ дан 30 November 2019 в 10:07
поделиться

С моей точки зрения, перечисления больше предназначены для удобства чтения, чем что-либо еще. В основном они используются для замены таких значений, как 1–6, на более описательные имена, например [Happy, Sad, Angry и т. Д.] Вы должны использовать их всякий раз, когда вам нужно использовать небольшой набор переменных для описания ожидаемого решения.

0
ответ дан 30 November 2019 в 10:07
поделиться
Другие вопросы по тегам:

Похожие вопросы: