权重随机算法的java实现

一、概述

  平时,经常会遇到权重随机算法,从不同权重的N个元素中随机选择一个,并使得总体选择结果是按照权重分布的。如广告投放、负载均衡等。

  如有4个元素A、B、C、D,权重分别为1、2、3、4,随机结果中A:B:C:D的比例要为1:2:3:4。

  总体思路:累加每个元素的权重A(1)-B(3)-C(6)-D(10),则4个元素的的权重管辖区间分别为[0,1)、[1,3)、[3,6)、[6,10)。然后随机出一个[0,10)之间的随机数。落在哪个区间,则该区间之后的元素即为按权重命中的元素。

  实现方法

利用TreeMap,则构造出的一个树为:
    B(3)
    /      \
        /         \
     A(1)     D(10)
               /
             /
         C(6)

然后,利用treemap.tailMap().firstKey()即可找到目标元素。

当然,也可以利用数组+二分查找来实现。

二、源码


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

package com.xxx.utils;

 

import com.google.common.base.Preconditions;

import org.apache.commons.math3.util.Pair;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

 

import java.util.List;

import java.util.SortedMap;

import java.util.TreeMap;

 

 

public class WeightRandom<K,V extends Number> {

    private TreeMap<Double, K> weightMap = new TreeMap<Double, K>();

    private static final Logger logger = LoggerFactory.getLogger(WeightRandom.class);

 

    public WeightRandom(List<Pair<K, V>> list) {

        Preconditions.checkNotNull(list, "list can NOT be null!");

        for (Pair<K, V> pair : list) {

            double lastWeight = this.weightMap.size() == 0 0 this.weightMap.lastKey().doubleValue();//统一转为double

            this.weightMap.put(pair.getValue().doubleValue() + lastWeight, pair.getKey());//权重累加

        }

    }

 

    public K random() {

        double randomWeight = this.weightMap.lastKey() * Math.random();

        SortedMap<Double, K> tailMap = this.weightMap.tailMap(randomWeight, false);

        return this.weightMap.get(tailMap.firstKey());

    }

 

}

  

  

三、性能

4个元素A、B、C、D,其权重分别为1、2、3、4,运行1亿次,结果如下:

元素 命中次数 误差率
A 10004296 0.0430%
B 19991132 0.0443%
C 30000882 0.0029%
D 40003690 0.0092%

从结果,可以看出,准确率在99.95%以上。

 

出处:http://www.cnblogs.com/waterystone/

 

 

 

现在app就是雨后春笋,嗖嗖的往外冒啊,有经验的、没经验的、有资历的、没资历的都想着创业,创业的90%以上都要做一个app出来,好像成了创业的标配。

做了app就得推广啊,怎么推,发券送钱是最多用的被不可少的了,现在好多产品或者运营都要求能够随机出优惠券的金额,但是呢又不能过于随机,送出去的券都是钱吗,投资人的钱,是吧。

所以,在随机生成的金额中就要求,小额度的几率要大,大额度的几率要小,比如说3元的70%,5块的25%,10块的5%,这个样子的概率去生成优惠券,这个怎么办呢?

对于上述的问题,直接用我们的Random.next(Integer range);就不够了。因为这个伪随机不带权重,3,5,10出现的概率都是一样的。

实现思路

还是拿上述的例子,3出现的概率是70%,我们给他的权重赋值为70,5出现的概率为25%,我们给他的权重赋值为25,10出现的概率为5%,我们给他的权重赋值为5.

我们按照顺序计算出权重的加和,把当前数字出现的权重加和前的值作为其权重范围的起点值,把加和后的值作为其权重范围的终点值。

这样的话,我们就可以使用Random.next(100)来做随机数,然后判断随机数落在的范围,然后映射到对应的优惠券数值即可。

java实现

package com.nggirl.test.weight.random;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Random;

public class WeightRandom {
    public static void main(String[] args){
        WeightRandom wr = new WeightRandom();
        wr.initWeight(new String[]{"1","2","3","4"}, new Integer[]{100,100,200,600});

        Random r = new Random();
        for(int i = 0; i < 10; i++){
            Integer rv = r.nextInt(wr.getMaxRandomValue());
            System.out.println(rv);
            System.out.println(wr.getElementByRandomValue(rv).getKey() + " " + rv);
        }

        HashMap<String, Integer> keyCount = new HashMap<String, Integer>();
        keyCount.put("1", 0);
        keyCount.put("2", 0);
        keyCount.put("3", 0);
        keyCount.put("4", 0);
        for(int i = 0; i < 10000; i++){
            Integer rv = r.nextInt(wr.getMaxRandomValue());
            String key = wr.getElementByRandomValue(rv).getKey();
            keyCount.put(key, keyCount.get(key).intValue()+1);
        }

        System.out.println("");
    }

    private List<WeightElement> weightElements;

    public void initWeight(String[] keys, Integer[] weights){
        if(keys == null || weights == null || keys.length != weights.length){
            return;
        }

        weightElements = new ArrayList<WeightElement>();

        for(int i=0; i< keys.length; i++){
            weightElements.add(new WeightElement(keys[i], weights[i]));
        }

        rangeWeightElemnts();

        printRvs();
    }

    private void rangeWeightElemnts(){
        if(weightElements.size() == 0){
            return;
        }

        WeightElement ele0 = weightElements.get(0);
        ele0.setThresholdLow(0);
        ele0.setThresholdHigh(ele0.getWeight());

        for(int i = 1; i < weightElements.size(); i++){
            WeightElement curElement = weightElements.get(i);
            WeightElement preElement = weightElements.get(i - 1);

            curElement.setThresholdLow(preElement.getThresholdHigh());
            curElement.setThresholdHigh(curElement.getThresholdLow() + curElement.getWeight());
        }
    }

    public WeightElement getElementByRandomValue(Integer rv){
        //因为元素权重范围有序递增,所以这里可以改为二分查找

        for(WeightElement e:weightElements){
            if(rv >= e.getThresholdLow() && rv < e.getThresholdHigh()){
                return e;
            }
        }

        return null;
    }

    public Integer getMaxRandomValue(){
        if(weightElements == null || weightElements.size() == 0){
            return null;
        }

        return weightElements.get(weightElements.size() - 1).getThresholdHigh();
    }

    public void printRvs(){
        for(WeightElement e:weightElements){
            System.out.println(e.toString());
        }
    }

    static class WeightElement{
        /**
         * 元素标记
         */
        private String key;
        /**
         * 元素权重
         */
        private Integer weight;
        /**
         * 权重对应随机数范围低线
         */
        private Integer thresholdLow;
        /**
         * 权重对应随机数范围高线
         */
        private Integer thresholdHigh;

        public WeightElement(){
        }

        public WeightElement(Integer weight){
            this.key = weight.toString();
            this.weight = weight;
        }

        public WeightElement(String key, Integer weight){
            this.key = key;
            this.weight = weight;
        }

        public String getKey() {
            return key;
        }
        public void setKey(String key) {
            this.key = key;
        }
        public Integer getWeight() {
            return weight;
        }
        public void setWeight(Integer weight) {
            this.weight = weight;
        }
        public Integer getThresholdLow() {
            return thresholdLow;
        }
        public void setThresholdLow(Integer thresholdLow) {
            this.thresholdLow = thresholdLow;
        }
        public Integer getThresholdHigh() {
            return thresholdHigh;
        }
        public void setThresholdHigh(Integer thresholdHigh) {
            this.thresholdHigh = thresholdHigh;
        }

        public String toString(){
            return "key:"+this.key + " weight:" + this.weight + " low:"+this.thresholdLow+" heigh:"+this.thresholdHigh;
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156

二分法的实现

    public WeightElement getElementByRandomValue(Integer rv){
        if(rv < 0 || rv > getMaxRandomValue()-1){
            return null;
        }

        //此时rv必然在0 - getMaxRandomValue()-1范围内,
        //也就是必然能够命中某一个值
        int start = 0, end = weightElements.size() - 1;
        int index = weightElements.size()/2;
        while(true){
            if(rv < weightElements.get(index).getThresholdLow()){
                end = index - 1;
            }else if(rv >= weightElements.get(index).getThresholdHigh()){
                start = index + 1;
            }else{
                return weightElements.get(index);
            }

            index = (start + end)/2;
        }
    }

 

http://blog.csdn.net/BuquTianya/article/details/51051672

 

基本算法描述如下:

1、每个广告增加权重 
2、将所有匹配广告的权重相加sum, 
3、以相加结果为随机数的种子,生成1~sum之间的随机数rd 
4、.接着遍历所有广告,访问顺序可以随意.将当前节点的权重值加上前面访问的各节点权重值得curWt,判断curWt >=  rd,如果条件成立则返回当前节点,如果不是则继续累加下一节点. 直到符合上面的条件,由于rd<=sum 因此一定存在curWt>=rd。 
特别说明:

此算法和广告的顺序无关 

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

import java.util.ArrayList;

import java.util.Collections;

import java.util.Comparator;

import java.util.LinkedHashMap;

import java.util.List;

import java.util.Map;

 

public class Test {

 

  /**

   * @param args

   */

  @SuppressWarnings("unchecked")

  public static void main(String[] args) {

     

    List<Node> arrNodes = new ArrayList<Node>();

    Node n = new Node(10, "测试1");

    arrNodes.add(n);

    n = new Node(20, "测试2");

    arrNodes.add(n);

    n = new Node(30, "测试3");

    arrNodes.add(n);

    n = new Node(40, "测试4");

    arrNodes.add(n);

     

    //Collections.sort(arrNodes, new Node());

    Map<String, Integer> showMap = null;

    int sum = getSum(arrNodes);

    int random = 0;

    Node kw = null;

    for(int k = 0; k < 20; k++) {

      showMap = new LinkedHashMap<String, Integer>();

      for(int i = 0; i < 100; i++) {

        random = getRandom(sum);

        kw = getKW(arrNodes, random);

        if(showMap.containsKey(kw.kw)) {

          showMap.put(kw.kw, showMap.get(kw.kw) + 1);

        } else {

          showMap.put(kw.kw, 1);

        }

        //System.out.println(i + " " +random + " " + getKW(arrNodes, random));

      }

      System.out.print(k + " ");

      System.out.println(showMap);

    }

  }

   

  public static Node getKW(List<Node> nodes, int rd) {

    Node ret = null;

    int curWt = 0;

    for(Node n : nodes){

      curWt += n.weight;

      if(curWt >= rd) {

        ret = n;

        break;

      }

    }

    return ret;

  }

  public static int getSum(List<Node> nodes) {

    int sum = 0;

    for(Node n : nodes)

      sum += n.weight;

    return sum;

  }

  public static int getRandom(int seed) {

    return (int)Math.round(Math.random() * seed);

  }

}

class Node implements Comparator{

  int weight = 0;

  String kw = "";

   

  public Node() {}

   

  public Node(int wt, String kw) {

    this.weight = wt;

    this.kw = kw;

  }

  public String toString(){

    StringBuilder sbBuilder = new StringBuilder();

    sbBuilder.append(" weight=").append(weight);

    sbBuilder.append(" kw").append(kw);

    return sbBuilder.toString();

  }

  public int compare(Object o1, Object o2) {

    Node n1 = (Node)o1;

    Node n2 = (Node)o2;

    if(n1.weight > n2.weight)

      return 1;

    else

      return 0;

  }

}

 

 

http://www.jb51.net/article/65058.htm

根据权重进行抽取的算法应用比较广泛,其中抽奖便是主要用途之一。正好这几天也正在进行抽奖模块的开发,整个抽奖模块涉及到的地方大概有三处,分别是后台进行奖品的添加(同时设置权重和数量),前台根据后台配置生成抽奖队列并根据指令开始抽奖活动,最后一部分是后台统计中奖情况并设置物流状态。本文主要针对前台抽奖算法进行介绍如何根据权重设置每个奖品被抽到的概率。

抽奖算法的核心是根据权重设置随机数出现的概率,在此我将它封装成一个生成随机数的随机类,代码如下:

 

[java] view plain copy

 

  1. /** 
  2.  * JAVA 返回随机数,并根据概率、比率 
  3.  *  
  4.  */  
  5. public class MathRandom {  
  6.       
  7.     private static Log logger = LogFactory.getLog(MathRandom.class);  
  8.   
  9.     /** 
  10.      * Math.random()产生一个double型的随机数,判断一下 每个奖品出现的概率 
  11.      *  
  12.      * @return int 
  13.      *  
  14.      */  
  15.     public int PercentageRandom(List<RewardPrize> prizes) {  
  16.         DecimalFormat df = new DecimalFormat("######0.00");    
  17.         int random = -2;  
  18.         try{  
  19.             double sumWeight = 0;  
  20.             //计算总权重  
  21.             for(RewardPrize rp_1 : prizes){  
  22.                 sumWeight += rp_1.getPrize_weight();  
  23.             }  
  24.             double randomNumber;  
  25.             randomNumber = Math.random();  
  26.             System.out.println("randomNumber是:" + randomNumber);  
  27.             double d1 = 0;  
  28.             double d2 = 0;  
  29.               
  30.             for(int i=0;i<prizes.size();i++){  
  31.                 d2 += Double.parseDouble(String.valueOf(prizes.get(i).getPrize_weight()))/sumWeight;  
  32.                 if(i==0){  
  33.                     d1 = 0;  
  34.                 }else{  
  35.                     d1 +=Double.parseDouble(String.valueOf(prizes.get(i-1).getPrize_weight()))/sumWeight;  
  36.                 }  
  37.                 if(randomNumber >= d1 && randomNumber <= d2){  
  38.                     random = i;  
  39.                     System.out.println("d1是:" + d1);  
  40.                     System.out.println("d2是:" + d2);  
  41.                     break;  
  42.                 }  
  43.             }  
  44.         }catch(Exception e){  
  45.             System.out.println(e.getMessage());  
  46.             logger.error("生成抽奖随机数出错,出错原因:" + e.getMessage());  
  47.             random = -1;  
  48.         }  
  49.         return random;  
  50.     }  
  51.   
  52.     /** 
  53.      * 测试主程序 
  54.      *  
  55.      * @param agrs 
  56.      */  
  57.     public static void main(String[] agrs) {  
  58.         int i = 0;  
  59.         MathRandom a = new MathRandom();  
  60.         List<RewardPrize> prizes = new ArrayList();  
  61.         for(int m=0;m<100;m++){  
  62.             RewardPrize rp = new RewardPrize();  
  63.             rp.setPrize_amount(10);//每个奖品数量设置10个  
  64.             rp.setPrize_weight(1);//每个奖品的权重都设置成1,也就是每个奖品被抽到的概率相同(可根据情况自行设置权重)  
  65.             prizes.add(rp);  
  66.         }  
  67.         for (i = 0; i <= 100; i++)// 打印100个测试概率的准确性  
  68.         {  
  69.             System.out.println(a.PercentageRandom(prizes));  
  70.         }  
  71.     }  
  72. }  

简单介绍一下上面的代码含义,首先计算出待选奖品的总权重,这样做的目的是可以随意设置奖品权重,不必再考虑权重之和是否等于100。随机规则是首先生成一个随机数randomNumber(生成的随机数位于0到1的左开右闭区间),然后分别计算出当前奖品前前面所有有奖品(不包括当前奖品)的概率和d1和当前奖品后面(包括当前奖品)所有奖品的概率和d2,然后判断生成的随机数randomNumber是否已处于d1和d2之间,如果处于该区间之内则当前奖品将被抽中。

 

http://blog.csdn.net/a1314517love/article/details/47276663

 

http://www.open-open.com/code/view/1455771789339

 

权重随机算法在抽奖,资源调度等系统中应用还是比较广泛的,一个简单的按照权重来随机的实现,权重为几个随机对象(分类)的命中的比例,权重设置越高命中越容易,之和可以不等于100;

简单实现代码如下:

    import java.util.ArrayList;
    import java.util.List;
    import java.util.Random;  

    public class WeightRandom {
        static List<WeightCategory>  categorys = new ArrayList<WeightCategory>();
        private static Random random = new Random();  

        public static void initData() {
            WeightCategory wc1 = new WeightCategory("A",60);
            WeightCategory wc2 = new WeightCategory("B",20);
            WeightCategory wc3 = new WeightCategory("C",20);
            categorys.add(wc1);
            categorys.add(wc2);
            categorys.add(wc3);
        }  

        public static void main(String[] args) {
              initData();
              Integer weightSum = 0;
              for (WeightCategory wc : categorys) {
                  weightSum += wc.getWeight();
              }  

              if (weightSum <= 0) {
               System.err.println("Error: weightSum=" + weightSum.toString());
               return;
              }
              Integer n = random.nextInt(weightSum); // n in [0, weightSum)
              Integer m = 0;
              for (WeightCategory wc : categorys) {
                   if (m <= n && n < m + wc.getWeight()) {
                     System.out.println("This Random Category is "+wc.getCategory());
                     break;
                   }
                   m += wc.getWeight();
              }  

        }  

    }  

    class WeightCategory {
        private String category;
        private Integer weight;  

        public WeightCategory() {
            super();
        }  

        public WeightCategory(String category, Integer weight) {
            super();
            this.setCategory(category);
            this.setWeight(weight);
        }  

        public Integer getWeight() {
            return weight;
        }  

        public void setWeight(Integer weight) {
            this.weight = weight;
        }  

        public String getCategory() {
            return category;
        }  

        public void setCategory(String category) {
            this.category = category;
        }
    }  

http://www.open-open.com/code/view/1423987535515

时间: 2025-01-27 01:53:03

权重随机算法的java实现的相关文章

Java随机算法(一)(r11笔记第14天)

问:如何生成一个随机的字符串?答:让新手退出VIM . 生成一个随机数看起来很简单,一直以来却深知它的不易,怎么让一个确定的值得到一个不确定的值,这个想起来都有点困难,而且这部分内容,自己也花了些时间去看Java源码,结果发现远比自己琢磨的要复杂的多,加上也有些日子没写过Java代码,可谓是困难重重,写了一小部分的总结发现,竟然有很多不大理解的地方.带着问题竟然找到一篇文章说得非常全面,索性就拿过来了.文章的链接如下,感兴趣可以看看,我在这个基础上做了删减. http://blog.sina.c

java web android-请教关于评论,喜欢,瞬发量的热度权重排名算法

问题描述 请教关于评论,喜欢,瞬发量的热度权重排名算法 请教大家,以下是我个人的一些思路,小白一个,大神勿喷: 假如说有瞬发量,喜欢,评论量和发布时间四个变量,首先说瞬发量,这里想到用户观看的时间,所以不能刷新太快,另外一个就是考虑到服务器的资源,在这里我就定为10分钟,比如说在这10分钟里有100个人访问,和50个人访问,那一分钟里的瞬发量就是10个和5个,(这里是用的分钟实际应该用秒哈):第二个就是喜欢,个人感觉喜欢和赞差不多,这个权重请教大家,第三个评论量也请大家给个建议,第四个创建发布时

多种负载均衡算法及其Java代码实现

首先给大家介绍下什么是负载均衡(来自百科) 负载均衡 建立在现有网络结构之上,它提供了一种廉价有效透明的方法扩展 网络设备和 服务器的带宽.增加 吞吐量.加强网络数据处理能力.提高网络的灵活性和可用性. 负载均衡,英文名称为Load Balance,其意思就是分摊到多个操作单元上进行执行,例如Web 服务器. FTP服务器. 企业关键应用服务器和其它关键任务服务器等,从而共同完成工作任务. 本文讲述的是"将外部发送来的请求均匀分配到对称结构中的某一台服务器上"的各种算法,并以Java代

多种负载均衡算法及其 Java 代码实现

首先给大家介绍下什么是负载均衡(来自百科) 负载均衡建立在现有网络结构之上,它提供了一种廉价有效透明的方法扩展 网络设备和 服务器的带宽.增加 吞吐量.加强网络数据处理能力.提高网络的灵活性和可用性. 负载均衡,英文名称为Load Balance,其意思就是分摊到多个操作单元上进行执行,例如Web 服务器. FTP服务器. 企业关键应用服务器和其它关键任务服务器等,从而共同完成工作任务. 本文讲述的是"将外部发送来的请求均匀分配到对称结构中的某一台服务器上"的各种算法,并以Java代码

最小生成树算法:Kruskal算法的Java实现

闲来无事,写个算法,最小生成树的Kruskal算法,相对比Prim算法实现起来麻烦一点点 package trees; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.PriorityQueue; import java.util.Set; /** * 最小生成树的Kruskal算法, * For a connected weighted graph G, a s

Dijkstra算法(三) Java详解

迪杰斯特拉算法介绍 迪杰斯特拉(Dijkstra)算法是典型最短路径算法,用于计算一个节点到其他节点的最短路径. 它的主要特点是以起始点为中心向外层层扩展(广度优先搜索思想),直到扩展到终点为止. 基本思想 通过Dijkstra计算图G中的最短路径时,需要指定起点s(即从顶点s开始计算). 此外,引进两个集合S和U.S的作用是记录已求出最短路径的顶点(以及相应的最短路径长度),而U则是记录还未求出最短路径的顶点(以及该顶点到起点s的距离). 初始时,S中只有起点s:U中是除s之外的顶点,并且U中

Floyd算法(三) Java详解

弗洛伊德算法介绍 和Dijkstra算法一样,弗洛伊德(Floyd)算法也是一种用于寻找给定的加权图中顶点间最短路径的算法.该算法名称以创始人之一.1978年图灵奖获得者.斯坦福大学计算机科学系教授罗伯特·弗洛伊德命名. 基本思想 通过Floyd计算图G=(V,E)中各个顶点的最短路径时,需要引入一个矩阵S,矩阵S中的元素a[i][j]表示顶点i(第i个顶点)到顶点j(第j个顶点)的距离. 假设图G中顶点个数为N,则需要对矩阵S进行N次更新.初始时,矩阵S中顶点a[i][j]的距离为顶点i到顶点

java算法-C# des算法转java des 结果不一致

问题描述 C# des算法转java des 结果不一致 C# 其中 provider.Mode加密为CBC provider.Padding为PKCS7 string data="-1"; byte[] rgbKey = {69, 70, 67, 49, 56, 49, 69, 70}; byte[] rgbIV = {54, 57, 51, 69, 52, 48, 55, 70}; MemoryStream ms = new MemoryStream(); CryptoStream

常见的一致性哈希算法#Java实现#

    之前参与过缓存框架的封装与测试工作,并对一致性哈希算法进行了相关的调研.通过对spymemcached与jedis等客户端源码的阅读对一致性哈希算法的Java实现进行调研: 1. 使用TreeMap实现,TreeMap本身继承NavigatableMap,因此具备节点导航的特点 2. 通过在内存中构建虚拟节点,每个物理节点存在160(默认值,可设置)个虚拟节点映射 1. 如何处理节点故障问题 源码分析:通过hash算法获取到的节点属于问题节点便进行N次的rehash操作,若执行N次的re