Как наиболее выгодно для памяти убедиться что массив содержит только разрешенные значения?
Какой метод можно применить для такой задачи:
-> получаем массив byte
-> прежде чем передать его в обработку, нужно убедиться что массив содержит только разрешенные значения (если надо, могу их запихнуть в отдельный массив/коллекцию) // самих значений около 20, значения добавляться или меняться не будут в будущем.
-> дальнейшие действия с массивом, если посторонних значений не выявлено
По идее, можно решить через ифы (если немного значений), либо написать отдельный boolean метод с перебором. Также наверняка есть готовые методы в языке типа ContainsAll() (он не подходит вроде бы). Еще не понятно что из этого будет эффективнее с точки зрения использования памяти.
Что эффективнее использовать в данном случае?
Ответы (2 шт):
Быстрее всего проверка выполняется при помощи преобразования массива допустимых байт в Set<Byte>, тогда можно написать метод для быстрой проверки при помощи Set::contains:
static Set<Byte> allowed = Set.of((byte)1, (byte)2, (byte)3, (byte)5, (byte)20);
public static boolean allGood(byte ... arr) {
for (byte b : arr) {
if (!allowed.contains(b)) return false;
}
return true;
}
public static boolean allGood(byte[] arr) {
for (byte b : arr) {
if (!allowed.contains(b)) return false;
}
return true;
}
Тест:
byte[] byteArray = {3, 2, 2, 1, 1, 5, 2};
System.out.println(allGood(byteArray)); // true
System.out.println(allGood((byte) 4, (byte)20, (byte)22)); // false
Аналогично, можно использовать массив битов BitSet, так как его максимальная длина составит не более 256:
public static boolean allGood(BitSet allowed, byte ... arr) {
System.out.print(Arrays.toString(arr) + " -> ");
for (byte b : arr) {
if (!allowed.get(0xFF & b)) return false;
}
return true;
}
Тест:
byte[] allowedValues = {1, 2, 3, 5, 20, -1, -128};
BitSet allowed = new BitSet(256);
for (byte b : allowedValues) {
allowed.set(b & 0xFF, true);
}
byte[] byteArray = {3, 2, 2, 1, 1, 5, 2, -1};
System.out.println(allGood(allowed, byteArray));
System.out.println(allGood(allowed, (byte) 4, (byte)20, (byte)22));
System.out.println(allGood(allowed, (byte) -1, (byte)20, (byte)-128));
Результат:
[3, 2, 2, 1, 1, 5, 2, -1] -> true
[4, 20, 22] -> false
[-1, 20, -128] -> true
Булев массив хранящий истину для хороших байт:
private static final boolean[] good = new boolean[256];
static {
String s = " *+-0123456789CDILMVX";
for (int i = 0; i < s.length(); ++i){
good[s.charAt(i)] = true;
}
};
private static boolean isGood(byte b) {
return good[Byte.toUnsignedInt(b)];
}
private static boolean isGood(byte[] bytes) {
for (byte b : bytes) {
if (!isGood(b)) {
return false;
}
}
return true;
}
public static void main(String[] args) {
System.out.println(isGood(new byte[]{48, 49}));
}