java简要实现优先级的分组排序
来源:互联网 发布:星游记网络大电影 编辑:程序博客网 时间:2024/05/18 01:31
本排序适用于内存排序,并且有强制的优先级
比如 有秒杀活动的 > 加入购物车 > 运营元素 > 店铺评分 > 历史购买 > 普通活动
本功能用户实际项目中搜索的展现以及推荐(当然优先级没有上面列的那么简单)
该版本性能还可以继续提供,因为时间有限,所以先出一个版本
csdn code 地址 : https://code.csdn.net/w172087242/littlehow/tree/master/src/main/java/littlehow/sort/group
排序元素准备:
bean包下:
OrderData(主要放置待排序的id和排序因子所对应的值)
package littlehow.sort.group.bean;import java.util.HashMap;import java.util.Map;import java.util.Set;/** * OrderData * * @author littlehow * @time 2017-08-14 11:23 */public class OrderData<T> { private T id; /** * 得分 */ private Map<String, Comparable> orderScoreMap; /** * 属性 */ private Map<String, Object> attribute; public void add(String key, Comparable value) { if (orderScoreMap == null) orderScoreMap = new HashMap<>(); orderScoreMap.put(key, value); } public Comparable get(String key) { if (orderScoreMap == null) return null; return orderScoreMap.get(key); } public Map<String, Comparable> getOrderScoreMap() { return orderScoreMap; } public void setAttribute(String key, Object value) { if (attribute == null) attribute = new HashMap<>(); attribute.put(key, value); } public Object getAttribute(String key) { if (attribute == null) return null; return attribute.get(key); } /** * 兼容前期已经调用的版本 * @param map */ @Deprecated public void setOrderScoreMap(Map<String, Double> map) { Set<Map.Entry<String, Double>> entrySet = map.entrySet(); for (Map.Entry<String, Double> entry : entrySet) { add(entry.getKey(), entry.getValue()); } } public T getId() { return id; } public void setId(T id) { this.id = id; } public boolean equalsProperty(OrderData<T> other, String key) { if (other == null) return false; return this.get(key).equals(other.get(key)); }}
OrderDirect 主要指明排序方向
package littlehow.sort.group.bean;/** * OrderDirect 排序方向 * * @author littlehow * @time 2017-08-14 11:10 */public enum OrderDirect { DESC(-1),//倒序 ASC(1)//正序 ; public final int v; OrderDirect(int v) { this.v = v; }}
OrderProperty 排序要素
package littlehow.sort.group.bean;/** * OrderProperty 排序要素 * * @author littlehow * @time 2017-08-14 11:11 */public class OrderProperty implements Comparable<OrderProperty> { /** * 要素标识 */ private String id; /** * 要素序号 */ private int ordinal; /** * 要素排序方向 */ private OrderDirect orderDirect; /** * 是否为是非因子 */ private boolean trueOrFalse; /** * 为null的时候的默认值 */ private Comparable defaultNullValue = 0.0; public OrderProperty() { } public OrderProperty(String id, int ordinal) { this.id = id; this.ordinal = ordinal; //默认倒序 this.orderDirect = OrderDirect.DESC; } public OrderProperty(String id, Integer ordinal, OrderDirect orderDirect) { this.id = id; this.ordinal = ordinal; this.orderDirect = orderDirect; } public OrderProperty(String id, int ordinal, OrderDirect orderDirect, boolean trueOrFalse) { this(id, ordinal, orderDirect); this.trueOrFalse = trueOrFalse; } public OrderProperty(String id, int ordinal, OrderDirect orderDirect, boolean trueOrFalse, Comparable defaultNullValue) { this(id, ordinal, orderDirect, trueOrFalse); this.defaultNullValue = defaultNullValue; } public String getId() { return id; } public void setId(String id) { this.id = id; } public int getOrdinal() { return ordinal; } public void setOrdinal(int ordinal) { this.ordinal = ordinal; } public OrderDirect getOrderDirect() { return orderDirect; } public void setOrderDirect(OrderDirect orderDirect) { this.orderDirect = orderDirect; } public boolean isTrueOrFalse() { return trueOrFalse; } public void setTrueOrFalse(boolean trueOrFalse) { this.trueOrFalse = trueOrFalse; } public Comparable getDefaultNullValue() { return defaultNullValue; } public void setDefaultNullValue(Comparable defaultNullValue) { this.defaultNullValue = defaultNullValue; } /** * 正序排列 ASC * @param other * @return */ public int compareTo(OrderProperty other) { return this.ordinal > other.ordinal ? 1 : this.ordinal == other.ordinal ? 0 : -1; } @Override public String toString() { return "{id=" + id + ", ordinal=" + ordinal + ", orderDirect=" + orderDirect + "}"; }}
OrderDataComparator主要用于因子值之间的排序
package littlehow.sort.group.bean;import java.util.Comparator;import java.util.List;/** * OrderDataComparator * * @author littlehow * @time 2017-08-15 15:50 */public class OrderDataComparator implements Comparator<OrderData> { private List<OrderProperty> orderProperties; public OrderDataComparator(List<OrderProperty> orderProperties) { this.orderProperties = orderProperties; } /** * 进行排序 * @param o1 * @param o2 * @return */ public int compare(OrderData o1, OrderData o2) { for (OrderProperty orderProperty : orderProperties) { //排序key String key = orderProperty.getId(); //排序默认值 Comparable dv = orderProperty.getDefaultNullValue(); //排序方向 OrderDirect orderDirect = orderProperty.getOrderDirect(); //元素一对应排序因子 Comparable c1 = o1.get(key); if (c1 == null) c1 = dv; //元素二对应排序因子 Comparable c2 = o2.get(key); if (c2 == null) c2 = dv; if (c1.compareTo(c2) == 0) { continue;//如果是一样的,则进行下一排序因子的比较 } return c1.compareTo(c2) * orderDirect.v; } //如果抵达这一步,证明前面要素比较全部一致,不需要进行元素交换 return 0; }}
utils包下
SortUtils 主要排序工具
package littlehow.sort.group.utils;import littlehow.sort.group.bean.OrderData;import littlehow.sort.group.bean.OrderDataComparator;import littlehow.sort.group.bean.OrderProperty;import java.util.Collections;import java.util.Comparator;import java.util.List;/** * SortUtil * * @author littlehow * @time 2017-08-14 11:42 */public abstract class SortUtils { /** * 进行实际排序 * @param orderDatas * @param orderProperties * @param max */ public static <T> void order(List<OrderData<T>> orderDatas, List<OrderProperty> orderProperties, int max) { //将要素要优先级排序, 优先级高的排在前面 Collections.sort(orderProperties); sort(orderDatas, new OrderDataComparator(orderProperties), max); } /** * * @param list * @param comparator * @param maxSize */ public static <T> void sort(List<OrderData<T>> list, Comparator<OrderData> comparator, int maxSize) { int length = list.size(); if (maxSize > length) maxSize = length; bubble(list, (Comparator) comparator, maxSize); } /** * 支持局部排序 * @param targets * @param comparator * @param maxSize -- 想要排序的数量 */ private static <T> void bubble(List<OrderData<T>> targets, Comparator comparator, int maxSize) { int length = targets.size(); for (int i = 0; i < maxSize; i++) { for (int j = i + 1; j < length; j++) { if (comparator.compare(targets.get(i), targets.get(j)) > 0) {//进行元素置换 swap(targets, i, j); } } } } /** * 元素交换 * @param targets * @param i * @param j * @param <T> */ private static <T> void swap(List<OrderData<T>> targets, int i, int j) { OrderData<T> tmp = targets.get(i); targets.set(i, targets.get(j)); targets.set(j, tmp); }}
CollectionUtils 集合工具,可以使用其他开源的集合工具,主要是不希望依赖太多
package com.kom.base.sort.utils;import java.lang.reflect.Field;import java.util.*;/** * CollectionUtils * * @author littlehow * @time 2017-06-09 10:07 */public class CollectionUtils { private static final List EMPTY_LIST = new ArrayList(); //私有构造,也可把类提取成抽象类 private CollectionUtils(){} /** * 判断集合是否为空 * @param collection * @return */ public static boolean isEmpty(Collection collection) { return collection == null || collection.isEmpty(); } /** * 判断集合非空 * @param collection * @return */ public static boolean isNotEmpty(Collection collection) { return !isEmpty(collection); } /** * 截取list * @param orig * @param startIndex * @param <T> * @return */ public static <T> List<T> subList(List<T> orig, int startIndex) { if (isEmpty(orig) || startIndex >= orig.size()) { return EMPTY_LIST; } if (startIndex == 0) return orig; return subList(orig, startIndex, orig.size()); } /** * 截取list集合 前闭后开区间, 如果起始位置为0,终止位置和集合总条数一致,则直接返回原有集合 * @param orig -- 要截取的集合 * @param startIndex -- 起始下标 * @param endIndex -- 终止下标但不包含该值 * @param <T> * @return */ public static <T> List<T> subList(List<T> orig, int startIndex, int endIndex) { if (isEmpty(orig) || startIndex >= endIndex || startIndex >= orig.size() || endIndex > orig.size()) { return EMPTY_LIST; } //如果起始位置为0,终止位置和集合总条数一致,则直接返回原有集合 if (orig.size() == endIndex && startIndex == 0) return orig; List<T> desc = new ArrayList<T>(endIndex - startIndex); for (int i = startIndex; i < endIndex; i++) { desc.add(orig.get(i)); } return desc; }}
service包下
SortService排序接口,主要便于以后扩展排序实现使用
package littlehow.sort.group.service;import littlehow.sort.group.bean.OrderData;import littlehow.sort.group.bean.OrderProperty;import java.util.ArrayList;import java.util.List;/** * SortService * * @author littlehow * @time 2017-08-16 13:58 */public abstract class SortService { /** * 全体排序 * @param orderDatas * @param orderProperties * @param <T> * @return */ public abstract <T> List<T> sort(List<OrderData<T>> orderDatas, List<OrderProperty> orderProperties); /** * 按照top max 排序 * @param orderDatas * @param orderProperties * @param maxSize * @param <T> * @return */ public abstract <T> List<T> sortMax(List<OrderData<T>> orderDatas, List<OrderProperty> orderProperties, int maxSize); /** * 分页排序 * @param orderDatas * @param orderProperties * @param pageNo * @param pageSize * @param <T> * @return */ public abstract <T> List<T> sortPaging(List<OrderData<T>> orderDatas, List<OrderProperty> orderProperties, int pageNo, int pageSize); /** * 获取id * @param orderDatas * @param start * @param end * @return */ public final <T> List<T> getIds(List<OrderData<T>> orderDatas, int start, int end) { List<T> ids = new ArrayList<>(orderDatas.size()); for (int i = start; i < end; i++) { ids.add(orderDatas.get(i).getId()); } return ids; }}
GroupSortService 分组排序实现类
package littlehow.sort.group.service;import littlehow.sort.group.bean.OrderData;import littlehow.sort.group.bean.OrderProperty;import littlehow.sort.group.utils.CollectionUtils;import littlehow.sort.group.utils.SortUtils;import java.util.List;/** * SortService * * @author littlehow * @time 2017-08-16 12:24 */public class GroupSortService extends SortService{ @Override public <T> List<T> sort(List<OrderData<T>> orderDatas, List<OrderProperty> orderProperties) { if (CollectionUtils.isEmpty(orderDatas)) return null; return sortMax(orderDatas, orderProperties, orderDatas.size()); } @Override public <T> List<T> sortMax(List<OrderData<T>> orderDatas, List<OrderProperty> orderProperties, int maxSize) { if (CollectionUtils.isEmpty(orderDatas) || CollectionUtils.isEmpty(orderProperties)) return null; if (orderDatas.size() == 1) {//只有一个元素就没有排序的必要 return getIds(orderDatas, 0, 1); } if (maxSize > orderDatas.size()) { maxSize = orderDatas.size(); } //进行排序 SortUtils.order(orderDatas, orderProperties, maxSize); return getIds(orderDatas, 0, maxSize); } @Override public <T> List<T> sortPaging(List<OrderData<T>> orderDatas, List<OrderProperty> orderProperties, int pageNo, int pageSize) { if (CollectionUtils.isEmpty(orderDatas) || CollectionUtils.isEmpty(orderProperties)) return null; int start = (pageNo - 1) * pageSize; int end = start + pageSize; //分页已经超出范围 if (start >= orderDatas.size()) return null; if (end > orderDatas.size()) { end = orderDatas.size(); } //进行排序 SortUtils.order(orderDatas, orderProperties, end); return getIds(orderDatas, start, end); }}
test包下
TestSort 简单的测试用例类
package littlehow.sort.group.test;import littlehow.sort.group.bean.OrderData;import littlehow.sort.group.bean.OrderDirect;import littlehow.sort.group.bean.OrderProperty;import littlehow.sort.group.service.GroupSortService;import littlehow.sort.group.service.SortService;import java.util.*;/** * TestSort * * @author littlehow * @time 2017-08-14 17:08 */public class TestSort { static double[] orderScore = {1.5, 1.8, 2.9, 3.3, 1.5, 1.6, 3.1, 2.9,0,1,2,1.6,0,1.5, 0.7, 0,7, 1.5, 1.5, 3.3, 1.6, 4.2,1,1,1.5, 4.1,1.5,1.6}; static double[] trueFalse = {0.0, 1.0}; static Random random = new Random(); static int length = orderScore.length; static SortService sortService = new GroupSortService(); private static List<OrderProperty> orderProperties = new ArrayList<OrderProperty>(); static { orderProperties.add(new OrderProperty("seckill", 1, OrderDirect.DESC, true)); orderProperties.add(new OrderProperty("cart", 2, OrderDirect.ASC, true)); orderProperties.add(new OrderProperty("marketingText", 3, OrderDirect.ASC)); orderProperties.add(new OrderProperty("shopScore", 4, OrderDirect.DESC)); orderProperties.add(new OrderProperty("historyPurchase", 5, OrderDirect.ASC)); orderProperties.add(new OrderProperty("activity", 6, OrderDirect.ASC)); } public static void main(String[] args) { test(); } static void test() { List<OrderData<Integer>> orderDatas = new ArrayList<>(); for (int i=1; i<11; i++) { orderDatas.add(getOrderData(i)); } for (OrderData orderData : orderDatas) { System.out.println(orderData.getId() + ":" + orderData.getOrderScoreMap()); }// System.out.println("========================分割==============================="); long start = System.currentTimeMillis(); for (int i=0;i<1;i++) {//Collections.shuffle(orderDatas);// for (OrderData orderData : orderDatas) {// System.out.print(orderIntData.getId()+"-");// }List<Integer> result = sortService.sortPaging(orderDatas, orderProperties, 1, 10); System.out.println(result); } System.out.println("-------------------->耗时:" + (System.currentTimeMillis() - start) + "毫秒"); } static OrderData getOrderData(int id) { OrderData orderData = new OrderData(); orderData.setId(id); orderData.setOrderScoreMap(getOrderScore()); return orderData; } static Map<String, Double> getOrderScore() { Map<String, Double> map = new HashMap<String, Double>(); for (OrderProperty orderProperty : orderProperties) { if (random.nextInt(10) < 4) continue; if (orderProperty.isTrueOrFalse()) { map.put(orderProperty.getId(), trueFalse[random.nextInt(2)]); } else { map.put(orderProperty.getId(), orderScore[random.nextInt(length)]); } } return map; }}
littlehow写于 2017-08-18 14:55
阅读全文
0 1
- java简要实现优先级的分组排序
- 堆排序及优先级队列Java实现
- orcale实现自定义优先级排序的SQL
- 实现通讯录分组排序的一个方法
- 抢占优先级和相应优先级以及优先级分组的理解
- Java实现遍历、排序、查找算法及简要说明
- sql实现分组排序
- App分组排序实现
- mysql实现分组排序
- MapReduce实现分组排序
- java中关于优先级队列的实现
- 分组校验和的java实现
- 使用Java实现Elasticsearch的分组功能
- 堆排序的应用之优先级队列的实现
- sql的分组排序
- sql实现分组并排序
- MYSQL 实现 MSSQL row_number() 类似的分组排序
- MySQL按最新时间分组排序的实现
- Lucene 搜索 一个测试程序
- 机器学习:一步步教你理解反向传播方法
- Python中的sorted函数以及operator.itemgetter函数
- MAC 下 CocoaPods 安装与使用来管理项目第三方框架
- 人生
- java简要实现优先级的分组排序
- USACO Section 1.5 Number Triangles
- 使用位运算总结(转载)
- kafka2:性能优化
- jq鼠标经过隐藏当前显示另一个
- python逻辑控制
- Delphi 動態創建控件,賦值,使用
- python3 爬虫时遇到问题:cannot use a string pattern on a bytes-like object
- css复习整理(三):盒子模型