Java 带有具有初始值的类实例的静态arraylist

Java 带有具有初始值的类实例的静态arraylist,java,arraylist,java-8,static-initialization,Java,Arraylist,Java 8,Static Initialization,我用一个静态arraylist创建了一个Coin类,它存储了创建的类的每个实例,但是我需要用一个初始实例启动这个列表,而且我还没有弄清楚如何在不添加两次的情况下(因为有多余的代码)完成它,有什么建议吗 public class Coin { private static ArrayList<String> coinNames = new ArrayList<>(); private static ArrayList<String> coinAb

我用一个静态arraylist创建了一个Coin类,它存储了创建的类的每个实例,但是我需要用一个初始实例启动这个列表,而且我还没有弄清楚如何在不添加两次的情况下(因为有多余的代码)完成它,有什么建议吗

public class Coin {
    private static ArrayList<String> coinNames = new ArrayList<>();
    private static ArrayList<String> coinAbbreviations = new ArrayList<>(Arrays.asList("CLP"));
    private static ArrayList<Coin> coins =
            new ArrayList<>(Arrays.asList(new Coin("Pesos chilenos", "CLP", 1f, "CLP")));
    private static HashMap<String,Float> exchangeRates;
    private String coinName;
    private String coinAbbreviation;
    private Float coinValue;
    private String unit;


    public Coin(String coinName, String coinAbbreviation, Float coinValue, String unit) {
        assert !coinAbbreviations.contains(coinAbbreviation) : "Coin abbreviation already used";
        assert coinAbbreviations.contains(unit) : "Coin unit non existent.";
        assert !coinNames.contains(coinName) : "Coin name already used.";
        this.coinName = coinName;
        this.coinAbbreviation = coinAbbreviation;
        this.coinValue = coinValue;
        this.unit = unit;

        coins.add(this);
    }
}
公共级硬币{
私有静态ArrayList coinNames=新ArrayList();
private static ArrayList coin缩写=新的ArrayList(Arrays.asList(“CLP”));
私人静态数组列表硬币=
新的ArrayList(Arrays.asList(新硬币(“比索奇列诺”,“CLP”,1f,“CLP”));
私有静态HashMap交换;
私有字符串名称;
私有字符串缩写;
私人浮动货币价值;
专用字符串单元;
公共硬币(字符串硬币名称、字符串硬币缩写、浮动硬币值、字符串单位){
断言!硬币缩写。包含(硬币缩写):“硬币缩写已使用”;
断言硬币缩写。包含(单位):“硬币单位不存在。”;
assert!coinNames.contains(coinName):“已使用币名。”;
this.coinName=coinName;
this.coin缩写=coin缩写;
this.coinValue=coinValue;
这个。单位=单位;
硬币。加上(这个);
}
}

如果你坚持要有可变的静态变量——通常这样做不是一个好主意——你可以这样做

private static ArrayList<Coin> coins =
        new ArrayList<>();

static {
  new Coin("Pesos chilenos", "CLP", 1f, "CLP");
}
私有静态数组列表=
新的ArrayList();
静止的{
新硬币(“比索奇列诺”,“CLP”,1f,“CLP”);
}

…这会立即将元素添加到列表中。

如果您坚持使用可变的静态变量--通常这样做根本不是一个好主意--您可以这样做

private static ArrayList<Coin> coins =
        new ArrayList<>();

static {
  new Coin("Pesos chilenos", "CLP", 1f, "CLP");
}
私有静态数组列表=
新的ArrayList();
静止的{
新硬币(“比索奇列诺”,“CLP”,1f,“CLP”);
}

…它会立即将元素添加到列表中。

什么阻止您在声明中初始化列表,然后将每个实例添加到构造函数中的列表?

什么阻止您在声明中初始化列表,然后将每个实例添加到构造函数中的列表?

您也可以选择使用一些最佳实践模式设计应用程序。您希望保留所有已创建硬币的注册表。最好将其保存在硬币类别之外。您可以有一个类来管理硬币的创建,并保存它创建的硬币的列表。如果您愿意,Coin类本身可以是一个接口,因为这样可以确保它只能由CoinFactory创建

public interface Coin {
    String name();
    String abbreviation();
    BigDecimal value();
    String unit();
}
以及硬币工厂类别:

public class CoinFactory {

    // Concrete coin is an internal implementation class whose details don't
    // need to be known outside of the CoinFactory class.
    // Users just see it as interface Coin.
    private static class ConcreteCoin implements Coin {
        private final String name;
        private final String abbreviation;
        private final BigDecimal value;
        private final String unit;

        ConcreteCoin(String name, String abbreviation, BigDecimal value, String unit) {
            this.abbreviation = abbreviation;
            this.name = name;
            this.value = value;
            this.unit = unit;
        }

        public String name() { return name; }
        public String abbreviation() { return abbreviation; }
        public BigDecimal value() { return value; }
        public String unit() { return unit; }
    }

    // Sets for enforcing uniqueness of names and abbreviations
    private Set<String> names = new HashSet<>();
    private Set<String> abbreviations = new HashSet<>();

    // All coins must have one of the following ISO currency codes as the 'unit' field.
    private final Set<String> allIsoCurrencyCodes =
            Set.of("CLP", "GBP", "EUR", "CAD", "USD", "XXX" /* , ... */);

    private List<Coin> allCoins = new ArrayList<>(
            List.of(createCoin("Pesos chilenos", "CLP", BigDecimal.ONE, "CLP")));

    private List<Coin> unmodifiableListOfAllCoins =
            Collections.unmodifiableList(allCoins);


    public Coin createCoin(String name, String abbreviation, BigDecimal value, String unit) {
        if (!names.add(name))
            throw new IllegalArgumentException("Name already exists: " + name);
        if (!abbreviations.add(abbreviation))
            throw new IllegalArgumentException("Abbreviation already exists: " + abbreviation);
        if (!allIsoCurrencyCodes.contains(unit))
            throw new IllegalArgumentException("Coin unit is not a recognised ISO currency code: " + unit);

        Coin coin = new ConcreteCoin(name, abbreviation, value, unit);
        allCoins.add(coin);
        return coin;
    }

    public Collection<Coin> allCoins() {
        return unmodifiableListOfAllCoins;
    }
}
公共类造币厂{
//Concrete coin是一个内部实现类,其详细信息不受限制
//需要在CoinFactory类之外知道。
//用户只是将其视为接口硬币。
私有静态类ConcreteCoin实现了Coin{
私有最终字符串名;
私有最终字符串缩写;
私有最终大十进制值;
专用最终字符串单元;
ConcreteCoin(字符串名称、字符串缩写、BigDecimal值、字符串单位){
这个缩写=缩写;
this.name=名称;
这个值=值;
这个。单位=单位;
}
公共字符串名称(){return name;}
公共字符串缩写(){返回缩写;}
public BigDecimal value(){return value;}
公共字符串单元(){return unit;}
}
//用于强制名称和缩写的唯一性的集合
私有集名称=新HashSet();
私有集缩写=新HashSet();
//所有硬币的“单位”字段必须包含以下ISO货币代码之一。
专用最终集allIsoCurrencyCodes=
“中电”、“英镑”、“欧元”、“加元”、“美元”、“XXX”/*、…*/);
私有列表allCoins=newarraylist(
(createCoin(“比索奇列诺”,“CLP”,BigDecimal.ONE,“CLP”));
私有列表不可修改的所有硬币列表=
收藏。不可修改列表(所有硬币);
公共硬币createCoin(字符串名称、字符串缩写、大十进制值、字符串单位){
如果(!name.add(name))
抛出新的IllegalArgumentException(“名称已存在:“+Name”);
如果(!缩写。添加(缩写))
抛出新的IllegalArgumentException(“缩写已存在:”+缩写);
如果(!allIsoCurrencyCodes.contains(单位))
抛出新的IllegalArgumentException(“硬币单位不是公认的ISO货币代码:“+单位”);
硬币=新的混凝土硬币(名称、缩写、价值、单位);
所有硬币。添加(硬币);
归还硬币;
}
公众收集所有硬币(){
返回所有硬币的不可修改列表;
}
}

您也可以使用一些最佳实践模式来设计应用程序。您希望保留所有已创建硬币的注册表。最好将其保存在硬币类别之外。您可以有一个类来管理硬币的创建,并保存它创建的硬币的列表。如果您愿意,Coin类本身可以是一个接口,因为这样可以确保它只能由CoinFactory创建

public interface Coin {
    String name();
    String abbreviation();
    BigDecimal value();
    String unit();
}
以及硬币工厂类别:

public class CoinFactory {

    // Concrete coin is an internal implementation class whose details don't
    // need to be known outside of the CoinFactory class.
    // Users just see it as interface Coin.
    private static class ConcreteCoin implements Coin {
        private final String name;
        private final String abbreviation;
        private final BigDecimal value;
        private final String unit;

        ConcreteCoin(String name, String abbreviation, BigDecimal value, String unit) {
            this.abbreviation = abbreviation;
            this.name = name;
            this.value = value;
            this.unit = unit;
        }

        public String name() { return name; }
        public String abbreviation() { return abbreviation; }
        public BigDecimal value() { return value; }
        public String unit() { return unit; }
    }

    // Sets for enforcing uniqueness of names and abbreviations
    private Set<String> names = new HashSet<>();
    private Set<String> abbreviations = new HashSet<>();

    // All coins must have one of the following ISO currency codes as the 'unit' field.
    private final Set<String> allIsoCurrencyCodes =
            Set.of("CLP", "GBP", "EUR", "CAD", "USD", "XXX" /* , ... */);

    private List<Coin> allCoins = new ArrayList<>(
            List.of(createCoin("Pesos chilenos", "CLP", BigDecimal.ONE, "CLP")));

    private List<Coin> unmodifiableListOfAllCoins =
            Collections.unmodifiableList(allCoins);


    public Coin createCoin(String name, String abbreviation, BigDecimal value, String unit) {
        if (!names.add(name))
            throw new IllegalArgumentException("Name already exists: " + name);
        if (!abbreviations.add(abbreviation))
            throw new IllegalArgumentException("Abbreviation already exists: " + abbreviation);
        if (!allIsoCurrencyCodes.contains(unit))
            throw new IllegalArgumentException("Coin unit is not a recognised ISO currency code: " + unit);

        Coin coin = new ConcreteCoin(name, abbreviation, value, unit);
        allCoins.add(coin);
        return coin;
    }

    public Collection<Coin> allCoins() {
        return unmodifiableListOfAllCoins;
    }
}
公共类造币厂{
//Concrete coin是一个内部实现类,其详细信息不受限制
//需要在CoinFactory类之外知道。
//用户只是将其视为接口硬币。
私有静态类ConcreteCoin实现了Coin{
私有最终字符串名;
私有最终字符串缩写;
私有最终大十进制值;
专用最终字符串单元;
ConcreteCoin(字符串名称、字符串缩写、BigDecimal值、字符串单位){
这个缩写=缩写;
this.name=名称;
这个值=值;
这个。单位=单位;
}