我想将很多应用程序功能存储到数据库中。我想为此使用一个表格行,所以我想使用位掩码来存储启用的功能。我试过这个:
HashMap<String, Integer> map = new HashMap<String, Integer>();
int database_value = 0;
public int setFeatureBitmask(int value) {
int bitmask = 0;
bitmask |= value;
return bitmask;
}
public static Set<String> processFeature(Integer bitmask) {
HashMap<String, Integer> newMap = new HashMap<String, Integer>();
return newMap.entrySet().stream().filter(e -> (e.getValue() & bitmask) == e.getValue()).map(e -> e.getKey())
.collect(Collectors.toSet());
}
@BeforeAll
public void setupData() {
System.out.println("Populating settings map");
map.put("Type1", 1);
map.put("Type2", 2);
map.put("Type3", 4);
map.put("Type4", 8);
map.put("Type5", 16);
map.put("Type6", 32);
map.put("Type7", 64);
map.put("Type8", 128);
map.put("Type9", 256);
map.put("Type10", 512);
map.put("Type11", 1024);
map.put("Type12", 2048);
map.put("Type13", 4096);
map.put("Type14", 8192);
map.put("Type15", 16384);
map.put("Type16", 32768);
map.put("Type17", 65536);
map.put("Type18", 131072);
map.put("Type19", 262144);
}
@Test
public void writeData() {
System.out.println("Converting Map using bitmasking");
for(int i=0; i<map.size(); i++) {
int number_value = map.get(i);
int result = setFeatureBitmask(number_value);
database_value = database_value + result;
}
}
@AfterAll
public void databaseInsert() {
System.out.println("Final resut to insert into Database " + database_value);
System.out.println("Converting back values from database");
// read here values from database_value variable and convert them into hash
}
第一个问题是例如如何将转换后的数字存储为一个大表值15990793
?我应该将所有转换后的数字组合成一个大数字吗?而且在我转换它们之后如何再次翻译它们以便我可以使用它们?
有没有工作的例子?我发现了很多位掩码示例,但没有像我的案例那样完整。完全不清楚如何获得工作结果你能建议吗?
编辑:
我测试了这个:
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import org.junit.FixMethodOrder;
import org.junit.jupiter.api.Test;
import org.junit.runners.MethodSorters;
@FixMethodOrder(MethodSorters.DEFAULT)
public class DatabaseFeaturesTest {
int opts = 0;
Map<Feature, Boolean> features = new HashMap<Feature, Boolean>();
Map<Feature, Boolean> featureMaps = new HashMap<Feature, Boolean>();
public void enableFeature(Feature feature) {
opts = opts | feature.getValue(); // Or regular sum
}
public void disableFeature(Feature feature) {
opts = opts & (~feature.getValue());
}
public boolean isFeatureEnabled(Feature feature) {
return (opts & feature.getValue()) != 0;
}
@Test
public void firstTest() {
System.out.println("Producing Features ");
features.put(Feature.A, true);
features.put(Feature.B, false);
}
@Test
public void secondTest() {
System.out.println("Converting Features for storage into Database");
int opts = features.entrySet().stream().filter(Entry::getValue)
.mapToInt(e -> e.getKey().getValue())
.sum();
System.out.println("produced value " + opts);
}
@Test
public void thirdTest() {
System.out.println("Reading from database ");
Map<Feature, Boolean> featureMaps =
Arrays.stream(Feature.values())
.collect(toMap(f -> f,
f -> (optsFromDatabase & f.getValue()) != 0,
(v1, v2) -> v2,
LinkedHashMap::new));
}
@Test
public void fourthTest() {
Boolean feature1 = featureMaps.get(Feature.A);
Boolean feature2 = featureMaps.get(Feature.B);
System.out.println("Reading from database Feature A " + feature1);
System.out.println("Reading from database Feature A " + feature2);
}
}
enum Feature {
A("Type1", 1), // 1 << 0
B("Type2", 2), // 1 << 1
C("Type3", 4), // 1 << 2,
F("Type6", 32); // 1 << 5
private final String featureName;
private final int value;
private Feature(String featureName, int value) {
this.featureName = featureName;
this.value = value;
}
public String getFeatureName() {
return featureName;
}
public int getValue() {
return value;
}
}
但是对于 toMap 我得到 The method toMap((<no type> f) -> {}, (<no type> f) -> {}, (<no type> v1, <no type> v2) -> {}, LinkedHashMap::new) is undefined for the type DatabaseFeaturesTest
我不喜欢使用随机常数来表达特征。
首先将您的功能包装到一个枚举中:
public enum Feature {
A("Type1", 1), // 1 << 0
B("Type2", 2), // 1 << 1
C("Type3", 4), // 1 << 2,
...
F("Type6", 32); // 1 << 5
private final String featureName;
private final int value;
// Constructor, getters/setters
}
假设您有变量int opts = 0
来存储您的特征组合。
现在要启用您执行的功能:
public void enableFeature(Feature feature) {
opts = opts | feature.getValue(); // Or regular sum
}
要禁用某个功能,您可以执行以下操作:
public void disableFeature(Feature feature) {
opts = opts & (~feature.getValues());
}
要测试某个功能是否已启用:
public boolean isFeatureEnabled(Feature feature) {
return (opts & feature.getValue()) != 0;
}
要将 a 转换Map<Feature, Boolean> features
为组合整数:
int opts = features.entrySet().stream().filter(Entry::getValue)
.mapToInt(e -> e.getKey().getValue())
.sum();
现在您将您opts
的数据库存储为常规整数。
读回来:
final int optsFromDatabase = ....; // Read that combination value from DB
Map<Feature, Boolean> featureMaps =
Arrays.stream(Feature.values())
.collect(toMap(f -> f,
f -> (optsFromDatabase & f.getValue()) != 0,
(v1, v2) -> v2,
LinkedHashMap::new));
您将恢复您的功能状态,例如:
{A=true, B=false, C=false, D=true, E=false, F=false ...}
更新
要支持许多功能(例如~100 个功能),您应该坚持使用 String。
现在,你应该修改你的Feature
类 abit:
public enum Feature {
A("Type1", 0), // index 0 in bit string
B("Type2", 1), // index 1 in bit String
C("Type3", 2), // index 2 in bit String
...
Z("TypeZ", 100); // index 100 in bit String
private final String featureName;
private final int index;
}
现在将您转换Map<Feature, Boolean>
为位字符串:
public String convertToDatabaseValue() {
return Arrays.stream(Feature.values()).map(f -> isFeatureEnabled(f) ? "1" : "0").collect(joining());
}
public Map<Feature, Boolean> initFromDatabaseValue(String bitString) {
// Note that, bitString length should equals to your number of feature. Or you have to padding it
char[] bitArray = bitString.toCharArray();
return Arrays.stream(Feature.values())
.collect(toMap(f -> f,
f -> bitArray[f.getIndex()] == '1',
(v1, v2) -> v2,
LinkedHashMap::new));
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句