TreeMap實現權重隨機數Java

  • 項目開發中在不少地方須要用到權重的分配資源的功能,在作中東電商項目中就遇到根據語言權重來獲取系統中語言出現的權重問題,下面作一個分享本身的實現方式

 

  • 用枚舉保存語言出現的權重(1)
 1 /**
 2  * @author yuguojin
 3  */
 4 public enum CommentLangIdEnum {
 5 
 6     ENGLISH(1, "英語", 15),
 7 
 8     ARABIC(2, "阿拉伯語", 85);
 9 
10     private int value;
11 
12     private String code;
13 
14     private int weight;
15 
16     CommentLangIdEnum(int value, String code, int weight) {
17         this.code = code;
18         this.value = value;
19         this.weight = weight;
20     }
21 
22     public int getValue() {
23         return value;
24     }
25 
26     public String getCode() {
27         return code;
28     }
29 
30     public int getWeight() {
31         return weight;
32     }
33 
34 }
  • 構建一個Pair對象存儲權重和對應的Key(2)
 1 /**
 2  * @author yuguojin
 3  * @param <K>
 4  * @param <V>
 5  */
 6 public class Pair<K, V> {
 7 
 8     private K key;
 9 
10     private V value;
11 
12     public Pair(K key, V value) {
13         this.key = key;
14         this.value = value;
15     }
16 
17     public K getKey() {
18         return key;
19     }
20 
21     public V getValue() {
22         return value;
23     }
24 }
  • 利用TreeMap實現存儲權重信息(3)
 1 import java.util.List;
 2 import java.util.SortedMap;
 3 import java.util.TreeMap;
 4 
 5 import com.google.common.base.Preconditions;
 6 
 7 /**
 8  * @author yuguojin
 9  * @param <K>
10  * @param <V>
11  */
12 public class WeightRandom<K, V extends Number> {
13     private TreeMap<Double, K> weightMap = new TreeMap<Double, K>();
14 
15     public WeightRandom(List<Pair<K, V>> list) {
16         Preconditions.checkNotNull(list, "list can NOT be null!");
17         for (Pair<K, V> pair : list) {
18             double lastWeight = this.weightMap.size() == 0 ? 0 : this.weightMap.lastKey().doubleValue();//統一轉爲double
19             this.weightMap.put(pair.getValue().doubleValue() + lastWeight, pair.getKey());//權重累加
20         }
21     }
22 
23     public K random() {
24         double randomWeight = this.weightMap.lastKey() * Math.random();
25         SortedMap<Double, K> tailMap = this.weightMap.tailMap(randomWeight, false);
26         return this.weightMap.get(tailMap.firstKey());
27     }
28 
29 }
  • 經過權重枚舉實現語言權重(4)
 1 import java.util.ArrayList;
 2 import java.util.List;
 3 
 4 import org.springframework.stereotype.Component;
 5 
 6 import com.appollo.product.common.enums.CommentLangIdEnum;
 7 
 8 /**
 9  * 
10  * @author yuguojin
11  *
12  */
13 @Component
14 public class CommentLangRandom {
15 
16     private static volatile WeightRandom<Integer, Integer> randomLanguageId;
17 
18     public int getLanguageId() {
19         initWeightRandom();
20         return randomLanguageId.random();
21     }
22 
23     private void initWeightRandom() {
24         if (null == randomLanguageId) {
25             synchronized (this) {
26                 if (null == randomLanguageId) {
27                     randomLanguageId = new WeightRandom<>(initStarsPair());
28                 }
29             }
30         }
31     }
32 
33     private List<Pair<Integer, Integer>> initStarsPair() {
34         List<Pair<Integer, Integer>> starsPair = new ArrayList<Pair<Integer, Integer>>();
35         for (CommentLangIdEnum starEnum : CommentLangIdEnum.values()) {
36             Pair<Integer, Integer> starPair = new Pair<Integer, Integer>(starEnum.getValue(), starEnum.getWeight());
37             starsPair.add(starPair);
38         }
39 
40         return starsPair;
41     }
42 }
  • 代碼備註

若是有相同的權重業務場景,只須要實現(1)中本身的權重分配枚舉,再實現(4)中的權重獲取方式就能夠用了;這裏只是作了靜態權重隨機的實現,若是對動態隨機感興趣的同事能夠留言java

相關文章
相關標籤/搜索