package me.test.biz; import java.util.LinkedList; import java.util.List; import java.util.ListIterator; import java.util.Queue; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * 平台商允许商户发布商品,但是显示时按照发布时间排序,按照商户分组; 最后需要额外处理,确保同一个商户发布的产品之间间隔随后3个其他商户的产品。 * <p> * 比如: (假设 11aaa 代表商户11的产品aaa ) * 1a,1b,1c,1d,1e, 2a,2b,2c,2d, 3a,3b,3c, 4a,4b, 5a,6a,7a * 应当处理为: * 1a,2a,3a,4a, 1b,2b,3b,4b, 1c,2c,3c,5a, 1d,2d,6a,7a, 1e */ public class TestOrder { public static final int INTERVAL = 3; public static class Item { int userId; String itemName; public String toString() { return userId + itemName; } } // 只有当商品有录入或者更新的时候才执行本方法,并将结果缓存。 // FIXME 如何避免商户恶意重新上下架商品,以使其商品 录入时间 最新,而获得更靠前的展示机会? // FIXME 如何避免商户恶意更新商品描述,以使其商品 修改时间 最新,而获得更靠前的展示机会? public static void main(String[] args) { // 模拟按照录入时间或者修改时间排好序的记录 String[] inputList = new String[]{ // 命名规则: "{num}{name}", 其中num为userId,name为商品名称 "1f", "101a", "102b", "1a", "1b", "1c", "1d", "1e", "2a", "2b", "2c", "2d", "3a", "3b", "3c", "4a", "4b", "5a", "6a", "7a", "8a" }; List<Item> itemList = toItemList(inputList); System.out.println("------------------------- 用户收入(已经按照一定规则排序过):"); System.out.println(itemList); List<Queue<Item>> groupedList = groupByUser(itemList); System.out.println("------------------------- 分组结果:"); System.out.println(groupedList); List<Item> sortedItemList = sort(groupedList); System.out.println("------------------------- 再排序后的结果为:"); System.out.println(sortedItemList); // TODO 存入缓存 } private static List<Item> toItemList(String[] inputList) { List<Item> itemList = new LinkedList<Item>(); Pattern p = Pattern.compile("^(\\d+)(\\S+)$"); for (String rec : inputList) { Matcher m = p.matcher(rec); if (!m.matches()) { throw new RuntimeException("输入格式不正确: `" + rec + "`"); } Item curItem = new Item(); curItem.userId = Integer.valueOf(m.group(1)); curItem.itemName = m.group(2); itemList.add(curItem); } return itemList; } private static List<Queue<Item>> groupByUser(List<Item> itemList) { List<Queue<Item>> groupedList = new LinkedList<Queue<Item>>(); Queue<Item> lastQueue = null; for (Item curItem : itemList) { if (lastQueue == null) { lastQueue = new LinkedList<Item>(); groupedList.add(lastQueue); } else { Item lastItem = lastQueue.peek(); if (lastItem.userId != curItem.userId) { lastQueue = new LinkedList<Item>(); groupedList.add(lastQueue); } } lastQueue.add(curItem); } return groupedList; } private static List<Item> sort(List<Queue<Item>> groupedList) { List<Item> sortedItemList = new LinkedList<Item>(); ListIterator<Queue<Item>> it = groupedList.listIterator(); while (it.hasNext()) { Queue<Item> lastQueue = it.next(); //int lastQueueIndex = it.nextIndex(); //System.out.println("lastQueue = [" + lastQueueIndex + "] " + lastQueue); Item item = lastQueue.poll(); if (item == null) { continue; } sortedItemList.add(item); // 当前列表已经空了,则继续 if (lastQueue.peek() == null) { continue; } // 当前列表还有元素,就要将后面其他用户的提前数据插入几个 int interval = 0; int forwardCount = 0; while (it.hasNext() && interval < INTERVAL) { Queue<Item> queue = it.next(); forwardCount++; Item i = queue.poll(); if (i == null) { continue; } sortedItemList.add(i); interval++; } for (int i = 0; i <= forwardCount; i++) { // 注意这里需要回退一次 it.previous(); // 这里一定不会抛出错误 } } return sortedItemList; } }