Java编程记录 --- 工具箱(填充中...)

本篇是记录自己在学习中遇到一些用法(比较泛,只要是我认为比较奇怪,惊艳的,有价值的都可以)。还有一些我经常会用到的和一些有趣的封装,先记录吧,可能后面多了会很乱,到时再说。

null字符串

这是一个很有意思的现象,我到现在才知道,原来会出现

String name = null;
System.out.println(name+"");
System.out.println(""+null); //"null"
System.out.println(String.valueOf(name)); //"null"

"null"这样的字符串。无论是""+null还是String.valueOf(name),Object name=null都会形成“null”字符串,而""+null的写法比较简洁,不会太长,所以一般我喜欢用前面一种(个人喜好)。

这里说这个现象的目的是:在判断字符串的时候,不要只考虑两种情况,还有第三种:

  1. 字符串为null
  2. 字符串为空字符串
  3. 字符串为"null"(null字符串)
String name = String.valueOf(...从request中获得请求参数)+""
if(name!=null && !"".equals(name) && "null".equals(name)){
    ...
}

32位的md5加密,全部小写(大写)

这个加密代码我是从网上查的,版本感觉都差不多,不过还有另外一种比较简洁的版本,下面会有说到。

/**
 *签名32位md5加密,全小写
 *
 */
public static String getSign(String account, String pwd, String timestamp)
    throws NoSuchAlgorithmException{
    String sign = account+pwd+timestamp;
    MessageDigest md5 = MessageDigest.getInstance("MD5");
    md5.update(sign.getBytes("UTF-8"));
    byte b[] = md5.digest();
    int i;
    StringBuffer sf = new StringBuffer("");
    for(int offset=0; offset<b.length; offset++){
        i = b[offset];
        if(i<0){
            i=i+256;
        }
        if(i<16){
            sf.append("0");
        }
        sf.append(Integer.toHexString(i));
        return sf.toString().toLowerCase();
    }
}

使用给定的密钥进行MD5加密,32位,大写,字符串用GBK编码。

/**
 * 用给定的密钥对字符串进行32位的md5加密,全大写,字符集采用GBK
 * @param str 待加密字符串
 * @param key 密钥
 * @return
 */
public static String getSign(String str, String key){
    StringBuffer sf = new StringBuffer("");
    try {
        MessageDigest md5 = MessageDigest.getInstance("MD5");
        md5.update(str.getBytes("GBK"));
        yte temp[] = md5.digest(key.getBytes("UTF-8"));
        for(int i=0; i<temp.length; i++){
            sf.append(Integer.toHexString((temp[i] & 0x000000FF) |
                        0xFFFFFF00).substring(6));
        }
        return sf.toString().toUpperCase();
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }
    return sf.toString().toUpperCase();
}

随机数

生成n位随机数

这是别人写的标题是链接,简单说一下原理,一开始现将,[0,1)*9+1=[1,10),然后根据需要将[1,10)*10^(n-1)。

/**
 * 生成n位随机数
 * @param n 随机数的长度
 * @return
 */
public static long getNDigitRanNum(int n){
    if(n < 1){
        throw new IllegalArgumentException("随机数位数必须大于0");
    }
    return (long)(Math.random()*9*Math.pow(10,n-1)) + (long)Math.pow(10,n-1);
}

自定义范围的随机数

/**
 * 生成指定上下界的随机数
 * [0, maxBound)%range=[0, range)+minBound=[minBound, minBound+range)
 * @param minBound 下界
 * @param maxBound 上界
 * @return
 */
public static int getRandomNumInRange(int minBound, int maxBound){
    Random random = new Random();
    return random.nextInt(maxBound)%(maxBound-minBound+1)+minBound;
}

随机事件(指定事件发生概率)

大致的需求是:比如说,有三种情况,第一种情况的出现概率为2/5;第二种情况的出现概率为2/5;最后一种出现的概率为1/5。实现的原理比较简单,复用上面的方法,然后对随机的区域进行分割,判定最后随机数落在哪个范围内,返回所需对应的字符串,具体看代码注释,代码有点乱。之所以写这个主要是有次写测试的时候,请求接口会返回三种状态,所以写了一个,感觉比较有趣就记下来了。。

/**
 * events:key(事件):value(概率),用TreeMap保持加入的顺序
 * 0.4,0.4,0.2
 * 400,800,1000
 * @param events 随机事件
 * @return
 */
public static String probabilityEvent(TreeMap<String, Double> events){
    double p_total = 1.0;
    int random = getRandomNumInRange(0, 1000); //取出随机范围为0~999的一个随机数
    int index = 0;
    String result = "";
    for(Map.Entry<String, Double> event : events.entrySet()){
        p_total = p_total - event.getValue(); //用于检查事件总概率小于1
        if("".equals(event.getKey().trim()) || event.getValue()<=0.0 || event.getValue()>=1.0){
            throw new IllegalArgumentException("事件不得为空,事件概率不能小于0大于1");
        }
        int range = (int)(event.getValue()*1000); //计算出该概率在1000中所占的范围
        index = index + range;
        //用""来控制不重复获取事件
        if("".equals(result) && random<index){
            result = event.getKey();
        }
    }
    if(p_total<0.0){
        throw new IllegalArgumentException("事件概率相加必须小于1");
    }
    return result;
}

猜你喜欢

转载自blog.csdn.net/qq_24986539/article/details/81132512