推荐业务经常会给出一个根据算法、规则等得到的有序id集合,web层需要调取其他的后端服务来拼接成为完整的dto实体,而其他的后端服务通常是黑盒的,而且由于缓存的存在以及sql执行的无序性,返回的结果的顺序很可能和推荐业务给出的结果不一样,那么就需要写很多复杂的逻辑来转换了,这非常麻烦,这里写了一个Reorder工具类,用来重新排序。
/**
* 保证集合有序性和输入序列一样
* @param identifier 通常用来获取输出序列的某个字段,该字段类型和输入序列一致方可排序
* @param orderList 输出序列
* @param originList 输入序列
* @return 按照输入序列排序的输出序列
*/
public static <T, K> List<T> reorder(Function<T, K> identifier, Collection<K> orderList, Collection<T> originList) {
Map<K, T> originMap = originList.stream().filter(Objects::nonNull).distinct().collect(Collectors.toMap(identifier, i -> i, (o, n) -> n));
return orderList.stream().map((id) -> {
if (!originMap.containsKey(id)) {
return null;
}
return originMap.get(id);
}).filter(Objects::nonNull).collect(Collectors.toList());
}
注释已经写的非常明确了,那么演示一下如何使用:
我从推荐业务获取了一个有序的id集合:lst 用lst去后端服务中拼接成了一个实体(Response)列表res 现在对res进行重排序
res = Reorder.reorder(Response::getId, lst, res);