Как представить 4 булевых возможностей в одном значении
Я хочу сохранить 4 логических параметра в одном значении. Например,
Я хочу одно значение, которое сообщает, является ли человек:
IsSingle
IsGraduate
IsMale
IsLookingForPartner
Так хорошо хранить их в байте, чьи 4 бита могут быть выделены, по одному для каждого параметра. Если бит установлен в 1, то этот логический параметр равен true. Поэтому я могу выполнять операции смены битов, чтобы найти, что все верно. если значение байта равно 111, тогда первые три параметра являются истинными. Это хороший способ? Есть ли лучший способ реализовать это?
Мне нужно сохранить это значение как единственный параметр в базе данных.
Ответы
Ответ 1
Бит-флаги.
public static final int IsSingle = 1 << 0;
public static final int IsGraduate = 1 << 1;
public static final int IsMale = 1 << 2;
public static final int IsLookingForPartner = 1 << 3;
...
if ((Value & IsSingle) != 0) {
}
if ((Value & IsGraduate) != 0) {
}
// Set "Single"
Value |= IsSingle;
// Remove "Graduate"
Value &= ~IsGraduate;
Ответ 2
Это действительно возможно сделать, однако это не рекомендуется.
Что делать, если вы хотите найти в своей базе данных всех студентов, которые не являются одинокими? Или мужчина?
Хотя пространство, которое вы сохраняете, минимально, вы отказываетесь от возможности индексировать свои данные для более быстрого поиска не только, но и для поиска любых данных, которые имеют критерии запроса, в зависимости от любого из этих атрибутов, вам необходимо выполнить операции смещения бит на всех записях (или проверке на несколько целых значений), которые в конечном итоге будут очень медленными.
Добавленная сложность на самом деле не приносит большой пользы в моем скромном мнении, базы данных могут обрабатывать 4 отдельных поля, и есть веские основания для этого делать (например, легко запрашивать данные на этих полях).
Ответ 3
Вы можете обнаружить, что EnumSet является естественным способом представления этой информации. EnumSet использует бит-маска под капотом.
enum Interest {
IsSingle,
IsGraduate,
IsMale,
IsLookingForPartner
}
EnumSet<Interest> interests = EnumSet.of(Interest.IsSingle, Interest.IsMale);
Вы можете добавить любое количество значений перечисления.
Ответ 4
Используйте двоичную упаковку. Определите для них константы как:
IsSingle = 1;
IsGraduate = 2;
IsMale = 4;
IsLookingForPartner = 8;
И объедините их с логической операцией ИЛИ. Таким образом, каждая возможность будет представлена битом в двоичном представлении числа. Вы можете проверить по AND-упакованное значение с любой из констант:
short status = IsSingle | IsMale; // will give 5
if ((status & IsMale) != 0)
System.out.println("Male.");
Ответ 5
Лучше всего было бы boolean[4]
, где вы сохраните каждое значение в другой ячейке массива и займет минимальное пространство!
напишите этот фрагмент кода в своем классе:
private boolean[] values = new boolean[4];
void setValue(String name, boolean value){
if(name=="IsSingle")
values[0] = value;
else if(name=="IsGraduate")
values[1] = value;
else if(name=="IsMale")
values[2] = value;
else if(name=="IsLookingForPartner")
values[3] = value;
}
boolean getValue(String name){
if(name=="IsSingle")
return values[0];
else if(name=="IsGraduate")
return values[1];
else if(name=="IsMale")
return values[2];
else if(name=="IsLookingForPartner")
return values[3];
else
return false;
}
теперь просто используйте это как: setValue("IsGraduate", true);
getValue("IsMale");
Ответ 6
Считаете ли вы использование байта для хранения значений? Затем вы можете сделать что-то вроде следующего:
public Byte setDetails(bool isSingle, bool isGraduate, bool isMale, bool isLooking)
{
Byte result = 0;
//Set the details
if (isSingle) result = result | 1;
if (isGraduate) result = result | 2;
if (isMale) result = result | 4;
if (isLooking) result = result | 8;
return result;
}
Затем вы можете использовать код, например:
Byte details = getDetails(true, false, true, false);
bool isSingle = (details & 1) != 0;
чтобы получить информацию.
... Тем не менее, ради трех байтов, стоит ли все дополнительные работы и константы?
Ответ 7
Если вы хотите использовать решение только для удовольствия, то ОК, но если это будет профессиональное приложение, НЕ реализуйте его в одном параметре в базе данных. Если вы это сделаете, подумайте об изменениях в бизнесе:
- Удалить isLookingForPartner//избыточный бит будет все время - порядок имеет значение
- Добавить новые параметры
- Найти всех людей, которые isLookingForPartner == true//будет медленным
Ответ 8
Вам нужно использовать отдельные переменные для их хранения. Человек может стать выпускником, одиноким мужчиной и искать партнера. Вы просто не можете хранить все эти возможности в одном булевом.