具有初始值的 Class 实例的静态数组列表
static arraylist with instances of Class with initial values
我正在用一个静态数组列表制作硬币 class,它存储创建的 class 的每个实例,但是我需要用一个初始实例启动该列表,但我还没有弄清楚如何不添加两次(因为冗余代码),有什么建议吗?
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);
}
}
如果您坚持使用可变静态变量——这样做通常根本不是一个好主意——您可以这样做
private static ArrayList<Coin> coins =
new ArrayList<>();
static {
new Coin("Pesos chilenos", "CLP", 1f, "CLP");
}
...立即将元素添加到列表中。
是什么阻止了您在声明中初始化列表,然后在构造函数中将每个实例添加到列表中?
您也可以使用一些最佳实践模式来设计您的应用程序。你想保留所有创建的硬币的注册表。最好将其保存在 Coin class 本身之外。你可以有一个 class 来管理硬币的创建并保留它创建的列表。如果您愿意,Coin class 本身可以是一个接口,因为这样可以确保它不能由 CoinFactory 以外的其他人创建。
public interface Coin {
String name();
String abbreviation();
BigDecimal value();
String unit();
}
和硬币工厂class:
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;
}
}
我正在用一个静态数组列表制作硬币 class,它存储创建的 class 的每个实例,但是我需要用一个初始实例启动该列表,但我还没有弄清楚如何不添加两次(因为冗余代码),有什么建议吗?
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);
}
}
如果您坚持使用可变静态变量——这样做通常根本不是一个好主意——您可以这样做
private static ArrayList<Coin> coins =
new ArrayList<>();
static {
new Coin("Pesos chilenos", "CLP", 1f, "CLP");
}
...立即将元素添加到列表中。
是什么阻止了您在声明中初始化列表,然后在构造函数中将每个实例添加到列表中?
您也可以使用一些最佳实践模式来设计您的应用程序。你想保留所有创建的硬币的注册表。最好将其保存在 Coin class 本身之外。你可以有一个 class 来管理硬币的创建并保留它创建的列表。如果您愿意,Coin class 本身可以是一个接口,因为这样可以确保它不能由 CoinFactory 以外的其他人创建。
public interface Coin {
String name();
String abbreviation();
BigDecimal value();
String unit();
}
和硬币工厂class:
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;
}
}