Здесь вы можете использовать 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,]
Перечисления в 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
}
Преимущества:
Типовая безопасность является проблемой, потому что в первом примере это допустимые операторы:
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 обычно дают вам обратную связь, если вы сравниваете перечисления разных типов, говоря, что они не могут быть равными, что может быть полезной и ранней формой проверки ошибок.
Перечисление 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, чтобы разделить перечисления и преобразовать их в целые числа. Это преобразование типов сохраняет все преимущества безопасности типов перечислений.
Документация Sun enum , вероятно, является лучшим объяснением. Конечно, вы можете обойтись и без них, как, конечно же, делали Java-программисты до выхода Java 1.5. Обычно то же самое можно сделать, используя константы в версиях Java до 1.5. Но перечисления очень удобны.
Если ситуация не возникает, тогда они вам не нужны.
Они позволяют вам иметь четко определенный набор вещей, например, если вы хотите представить состояния из того, что вы могли бы иметь:
enum MatterState {
Solid,
Liquid,
Gas;
}
Где они превзошли старый стиль использования объектов для представления наборов несколькими способами, некоторые из которых:
Думайте о 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;
}
Оба аналогичны
в отношении,
С моей точки зрения, перечисления больше предназначены для удобства чтения, чем что-либо еще. В основном они используются для замены таких значений, как 1–6, на более описательные имена, например [Happy, Sad, Angry и т. Д.] Вы должны использовать их всякий раз, когда вам нужно использовать небольшой набор переменных для описания ожидаемого решения.