我有一个“配置”类,该类成为其他几个类的字段。它指示那些其他类的某种配置或“功能”,以允许或禁止操作。截至目前,配置类包含一组四个独立的布尔值,并且可能会保持原样(或与另一个布尔值一起增长)。配置是不变的:创建对象后,配置将永远不会更改。

public class Configuration {
    private final boolean abilityOne;
    private final boolean abilityTwo;
    private final boolean abilityThree;
    private final boolean abilityFour;

    public Configuration (final boolean abilityOne, final boolean abilityTwo,
                          final boolean abilityThree, final boolean abilityFour) {
    this.configuration = ((1 * (abilityOne ? 1 : 0)) +
            (2 * (abilityTwo ? 1 : 0)) +
            (4 * (abilityThree ? 1 : 0)) +
            (8 * (abilityFour ? 1 : 0)));
 }

    public boolean isAbilityOne() {
        return((1 & this.configuration) > 0);
    }

    public boolean isAbilityTwo() {
        return((2 & this.configuration) > 0);
    }

    public boolean isAbilityThree() {
        return((4 & this.configuration) > 0);
    }

    public boolean isAbilityFour() {
        return((8 & this.configuration) > 0);
    }
}

由于C /有限硬件背景,我的下一个实现(尝试减少内存占用)是将int用作位图:1->第一个布尔值,2->第二,4->第三,8->第四位。这样,我存储一个整数,我需要的布尔函数就像:

它工作正常,并且内存效率很高。但这让我一辈子的Java同事都不满意。

不同配置的数量是有限的(布尔值的组合),但是使用它们的对象数量非常大。为了减少内存消耗,我想到了某种“多单例”,枚举或缓存实例。这就是我现在的位置。什么是最好的?

最佳答案

我认为Multiton模式是执行此操作的最有效方法:

public class Configuration {

    private static Map<Long, Configuration> configurations = new HashMap<>();

    private long key;
    private long value;

    public static Configuration getInstanse(long key, boolean... configs) {
        if (configurations.containsKey(key)) {
            return configurations.get(key).setConfigs(configs);
        }
        Configuration configuration = new Configuration(key, configs);
        configurations.put(key, configuration);
        return configuration;
    }

    // Max number of configs.length is 64
    private Configuration(long key, boolean... configs) {
        this.key = key;
        setConfigs(configs);
    }

    private Configuration setConfigs(boolean[] configs) {
        this.value = 0L;
        boolean config;
        for (int i = 0; i < configs.length; i++) {
            config = configs[i];
            this.value = this.value | (config ? (1L << i) : 0L);
        }
    }

    public long getKey() {
        return key;
    }

    public boolean getConfig(int place) {
        return (value & (1L << place)) == (1L << place);
    }
}

09-30 14:28