目前,我的应用程序中有以下设计,即使用enum
作为内存有效常量
public enum Board {
Toronto // Toronto stock Exchange
}
public class Stock {
private final Board board;
private final Code code;
....
}
这是一种记忆效率高的方式。因为,如果证券交易所中有数千Stock
,则只会创建一个Board
个实例。
Stock stock0 = new Stock(Code.newInstance("AAA.TO"), Board.Toronto);
Stock stock1 = new Stock(Code.newInstance("AAB.TO"), Board.Toronto);
然而,这当然有一些缺点。证券交易所将不时推出新的董事会。发生此类事件时,我需要
Board
public enum Board {
Toronto, // Toronto stock Exchange
TSXV // New Toronto venture
}
Stock stock0 = new Stock(Code.newInstance("AAA.TO"), Board.Toronto);
Stock stock1 = new Stock(Code.newInstance("AAB.TO"), Board.Toronto);
Stock stock2 = new Stock(Code.newInstance("TRU.V"), Board.TSXV);
我想避免这么不方便。我最初的计划是
public class Board {
private final String board;
private Board(String board) {
this.board = board;
}
public Board newInstance(String board) {
return new Board(board);
}
}
然而,这不是一种记忆效率高的方式。因为,将创建Board
的多个实例。
// 2 Toronto board instance will be created! Not memory efficient when we have huge stock list.
Stock stock0 = new Stock(Code.newInstance("AAA.TO"), Board.newInstance("Toronto"));
Stock stock1 = new Stock(Code.newInstance("AAB.TO"), Board.newInstance("Toronto"));
Stock stock2 = new Stock(Code.newInstance("TRU.V"), Board.newInstance("TSXV"));
我想知道,我可以应用什么样的数据结构,这样我就可以用一种记忆效率的方式来表示常量(在我的上下文中,它意味着Board
类)
我不想使用String
,因为我更喜欢安全类型,以区分Board
和真实String
。
答案 0 :(得分:2)
伪代码:
public class Board {
private static final Set<Board> boards = new HashSet<>();
public static Board getInstance(String board) {
//search if board already exists on boards set, if it is, return that instance; else, add to list and return the newly created instance.
}
//override equals and hashCode appropriately
}
答案 1 :(得分:1)
这是一种线程安全的方式。我不确定这种实现是否可以视为Flyweight模式。但是,我尽最大努力确保它是线程安全的。如果您发现任何可能的错误,请随时修改代码。
import java.util.concurrent.ConcurrentHashMap;
/**
*
* @author yccheok
*/
public class Board {
private Board(String board) {
this.board = board;
}
public static Board newInstance(String board) {
if (board == null) {
throw new java.lang.IllegalArgumentException("board cannot be null");
}
Board result = map.get(board);
if (result == null) {
final Board instance = new Board(board);
result = map.putIfAbsent(board, instance);
if (result == null) {
return instance;
}
}
assert(result != null);
return result;
}
@Override
public int hashCode() {
int result = 17;
result = 31 * result + board.hashCode();
return result;
}
@Override
public boolean equals(Object o) {
if (o == this) {
return true;
}
if (!(o instanceof Board)) {
return false;
}
return this.board.equals(((Board)o).board);
}
@Override
public String toString() {
return board;
}
// Avoid using interface. We want it to be fast!
private static final ConcurrentHashMap<String, Board> map = new ConcurrentHashMap<>();
private final String board;
}
答案 2 :(得分:0)
在我看来,最好的解决方案是将Board添加到您的数据库中,当业务部门提出新的董事会时您必须更新数据库,您的董事会可能会日复一日地改变以适应业务需求,因此它不适合Constant或Enum