java 参数排序_java学习-排序及加密签名时数据排序方式

排序有两种

在java中一般实现集合排序的方式有两种。

1. 类实现Comparable接口的compareTo(T o)接口方法2. 使用 Comparator接口的 compare(T o1, T o2)接口方法

在具体的调用上。

1. 类实现comparable接口调用List.sort(null)或Collections.sort(List)方法进行排序

jdk内置的基本类型包装类等都实现了Comparablel接口,默认是使用自然排序,即升序排序

自定义类实现Comparable接口必须要实现compareTo()方法,自己定义排序方式

2.List中T没有实现Comparable类接口方法,又想将对象列表进行排序时,

上面的两种排序方式底层都是采用归并排序算法,是稳定的排序算法。时间复杂度(nlog2n),空间复杂度(n) 十大经典排序算法(动图演示)

重写这两种方式的接口方法

这两个接口方法的重写逻辑是一样的,都要满足以下条件

关系满足传递性:(compare(x,y)> 0 )&&(compare(y,z)> 0))意味着compare(x,z)> 0

升序:o1>o2 返回1 并且 o1

降序:o1>o2 返回-1 并且 o1

Comparable接口方法升序public int compareTo(into2){if(this.value >o2){return 1;

}if(this.value =o2){return 0;

}if(this.value

}

}

Comparator接口方法升序int compare(int o1, into2);if(o1 >o2){return 1;

}if(o1 =o2){return 0;

}if(o1

}

}

使用场景:

1.调用别人接口获取数据时候,需要将参数按照字典排序排序对数据进行签名,与返回的签名数据进行对比,验证数据的完整性。

2.对获取的数据进行排序后返回给前端,除了使用sql的order asc命令外,也可以使用list.sort方法进行排序后返回给前端(有点傻^^)。

3. 用于复杂的排序场景,比如文件名的排序,广东-广州-期末测试1,广西-桂林-期末测试2,需要我们自己控制排序方法,这时候就需要用到上面两个排序。

实现Comparable接口的排序

consumInfo.java类

实现comparable接口,使用升序排序

public class ConsumInfo implements Comparable{public doubleprice;publicString name;public ConsumInfo(doubleprice, String name) {super();this.price =price;this.name =name;

}

@Overridepublic intcompareTo(ConsumInfo o) {//首先比较price,如果price相同

if (this.price >o.price) {return 1;

}if (this.price ==o.price) {return 0;

}return -1;

}

}

来个简单的测试

ConsumInfo []cc=new ConsumInfo[4];

cc[0] = new ConsumInfo(1.1, "zwh");

cc[1] = new ConsumInfo(2.5, "abc");

cc[2] = new ConsumInfo(0.1, "zwh");

cc[3] = new ConsumInfo(0.1, "cdf");

Arrays.sort(cc);for(ConsumInfo consumInfo:cc) {

System.out.println("name:"+consumInfo.name+" price:"+consumInfo.price);

}

结果

name:zwh price:0.1

name:cdf price:0.1

name:zwh price:1.1

name:abc price:2.5

如果要先按照price排序,如果price相等,再按name进行升序排序呢

只需要修改conpareTo()方法,在price相等时,在比较name的值

@Overridepublic intcompareTo(ConsumInfo o) {//首先比较price,如果price相同

if (this.price >o.price) {return 1;

}if(this.price==o.price) {return this.name.compareTo(o.name);

}return -1;

}

修改后的输出结果,

这里name是String类型,默认是按照字典顺序排序,也就是升序排序。

cdf和zwh,,c比z小,所以调换了位置

name:cdf price:0.1name:zwh price:0.1name:zwh price:1.1name:abc price:2.5

使用Comparator接口实现排序

还是使用上面的ConsumInfo.java类

ConsumInfo []cc=new ConsumInfo[4];

cc[0] = new ConsumInfo(1.1, "zwh");

cc[1] = new ConsumInfo(2.5, "abc");

cc[2] = new ConsumInfo(0.1, "zwh");

cc[3] = new ConsumInfo(0.1, "cdf");

Arrays.sort(cc,new Comparator() {

@Overridepublic intcompare(ConsumInfo o1, ConsumInfo o2) {if(o1.price

}if(o1.price==o2.price) {returno1.name.compareTo(o2.name);

}return 1;

}

});for(ConsumInfo consumInfo:cc) {

System.out.println("name:"+consumInfo.name+" price:"+consumInfo.price);

}

使用了Arrays.sort(T[] a, Comparator super T> c)排序方法,会把ConsumInfo所实现的Comparable接口的排序方法替换掉

也就是说只会使用Comparator接口进行排序。

上面的排序是用于List或者数组或集合的排序,

对于Map,需要对map的key值进行升序排序

使用TreeMap类进行自动排序,默认升序排序。

Map para = new TreeMap();

para.put("zwh", "123456");

para.put("abc", "123456");

para.put("wuv", "123456");

para.put("cdg", "123456");for (Map.Entryentry : para.entrySet()) {

System.out.println("key:" + entry.getKey() + " value:" +entry.getValue());

}

结果

key:abc value:123456

key:cdg value:123456

key:wuv value:123456

key:zwh value:123456

/***

* 方法用途: 对所有传入参数按照字段名的Unicode码从小到大排序(字典序),并且生成url参数串

* 实现步骤:

*

*@paramparaMap 要排序的Map对象

*@paramurlEncode 是否需要对value的值进行编码

*@paramkeyToLower 是否需要将Key转换为全小写

* true:key转化成小写,false:不转化

*@return

*/

public static String formatUrlMap(Map paraMap, boolean urlEncode, booleankeyToLower) {

String buff= "";

Map tmpMap =paraMap;try{

List> infoIds = new ArrayList>(tmpMap.entrySet());//对所有传入参数按照字段名的 ASCII 码从小到大排序(字典序)

Collections.sort(infoIds, new Comparator>() {

@Overridepublic int compare(Map.Entry o1, Map.Entryo2) {return(o1.getKey()).toString().compareTo(o2.getKey());

}

});//构造URL 键值对的格式

StringBuilder buf = newStringBuilder();for (Map.Entryitem : infoIds) {if (item.getKey() != null) {

String key=item.getKey();

String val=item.getValue();if(urlEncode) {

val= URLEncoder.encode(val, "utf-8");

}if(keyToLower) {

buf.append(key.toLowerCase()+ "=" +val);

}else{

buf.append(key+ "=" +val);

}

buf.append("&");

}

}

buff=buf.toString();if (buff.isEmpty() == false) {

buff= buff.substring(0, buff.length() - 1);

}

}catch(Exception e) {return null;

}returnbuff;

}

参考支付宝的参数排序方法

剔除sign字段(这个根本不需要剔除,参数中是没有的),

剔除参数值为空的字段,这里做了个简单的判断,

对key进行排序,然后用&符号对key=value进行拼接。

Map para = new TreeMap();

para.put("app_id", "2014072300007148");

para.put("method", "alipay.mobile.public.menu.add");

para.put("charset", "");

para.put("sign_type", "");

para.put("timestamp", "2014-07-24 03:07:50");

para.put("biz_content", "");

para.put("sign_type", "123456");

para.put("version", "1.0");

List keys= new ArrayList<>(para.keySet());

Collections.sort(keys);

StringBuffer content=newStringBuffer();for (int i=0; i

String key=keys.get(i);

String value=para.get(key);if(value!=null&&value.length()!=0) {

content.append((i==0?"":"&")+key+"="+value);

}

}

System.out.println(content.toString());

结果

app_id=2014072300007148&method=alipay.mobile.public.menu.add&sign_type=123456&timestamp=2014-07-24 03:07:50&version=1.0

注意,上面字符串的空判断还少做了一个空白字符的判断,建议使用下面的值的非空判断代替

if(value!=null&&value.length()!=0)

public static booleanisBlank(String str) {intstrLen;if (str == null || (strLen = str.length()) == 0) {return true;

}for (int i = 0; i < strLen; i++) {if ((Character.isWhitespace(str.charAt(i)) == false)) {return false;

}

}return true;

}

待看:http://www.cnblogs.com/interdrp/p/8970593.html Java Comparator字符排序(数字、字母、中文混合排序)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值