2015-04-02 17 views
0

目前,我在我的應用程序,它使用enum高效記憶恆定技術在運行時創建常數的內存使用效率,

public enum Board { 
    Toronto // Toronto stock Exchange 
} 

public class Stock { 
    private final Board board; 
    private final Code code; 
    .... 
} 

這是一個內存高效的方法下面的設計。因爲,如果證券交易所中有成千上萬的Stock,則只會創建1個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和real String

+0

使用[flyweight pattern](http://en.wikipedia.org/wiki/Flyweight_pattern)。 – 2015-04-02 03:48:05

+0

@LuiggiMendoza我通過了你的建議,通過使用一個線程安全的方式:我已經通過了你的想法http://stackoverflow.com/a/29405169/72437 – 2015-04-02 04:51:47

回答

1

這是一個線程安全的方式來適應業務需求。我不確定這樣的實現是否可以被視爲享元模式。但是,我盡了最大的努力來確保它是線程安全的。如果您發現任何可能的錯誤,請隨時修改代碼。

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

嗯,如何有關存儲在一組或映射板?這樣你可以保證每個只有一個實例。

僞代碼:

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 
} 
+0

,但在一個線程安全的方式:http://stackoverflow.com/a/29405169/72437 – 2015-04-02 04:51:04

0

在我看來,最好的解決辦法是板添加到您的數據庫,你必須在業務方面提出了新的董事會,以更新數據庫,你可以改變電路板一天一天所以它不適合這樣做的常量或枚舉

+0

這與數據庫完全無關。 – 2015-04-02 04:52:37