队列:推荐结果打散
什么是推荐结果打散?
以小视频推荐的那种功能为例,为了圆子,都是包含广告和小视频的。
那肯定不能全部推荐广告,必须是几个视频中夹杂着广告,比如你刷了20个,就给你弹一个广告出来,是有一个固定的顺序的。
推荐结果打散就是确保每个广告和广告之间,确保包含几个视频,这种效果。
代码
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
/**
* 以小视频推荐的那种功能为例,为了圆子,都是包含广告和小视频的。
* <p>
* 那肯定不能全部推荐广告(ad),必须是几个视频(video)中夹杂着广告,比如你刷了20个,就给你弹一个广告出来,是有一个固定的顺序的。
* <p>
* 推荐结果打散就是确保每个广告和广告之间,确保包含几个视频,这种效果。
*/
public class KanDianTest {
/**
* 获得被推荐的结果
*
* @param adAndVideo: ad和video的集合
* @param maxInterval: ad和video的间隙数量,自首个ad出现后,每maxInterval个video后,后面必然是一个ad
* @return
*/
public List<String> getRecommendenResult(List<String> adAndVideo, int maxInterval) {
List<String> result = new ArrayList<>();
if (adAndVideo == null || adAndVideo.size() == 0) {
return result;
}
/*声明两个队列,一个是存储video,一个存储ad*/
Queue<String> videoQueue = new LinkedList<>();
Queue<String> adQueue = new LinkedList<>();
boolean firstAd = false;//判断开头是否是ad
int index = 0;
int adAndVideoSize = adAndVideo.size();
while (!firstAd && index < adAndVideoSize) {//判断有没有firstAd,第一次出现ad则跳出此循环,否则一直向result添加video
if (isVideo(adAndVideo.get(index))) {//adAndVideo index=0为ad,则不执行result.add
result.add(index, adAndVideo.get(index));
index++;
} else {
firstAd = true;
}
}
/*向各自的队列添加元素*/
while (index < adAndVideoSize) {
if (isVideo(adAndVideo.get(index))) {
videoQueue.add(adAndVideo.get(index));
} else {
adQueue.add(adAndVideo.get(index));
}
index++;
}
/*两个队列都不为空,开始向结果队列添加元素*/
int currentSize = result.size();//用来验证result中video的数量,代表video和ad的间隙,首次为第一次出现ad的下标
while (!videoQueue.isEmpty() && !adQueue.isEmpty()) {
if (currentSize >= maxInterval) {//数量>允许存在的ad的数量,加ad
result.add(adQueue.poll());
currentSize = 0;//添加ad后,间隙归零,重新计算
} else {//不大于,加video,adAndVideo index=0为ad,就是走的这个
result.add(videoQueue.poll());
currentSize++;
}
}
/*ad放完之后,video仍存在,则加完video*/
while (!videoQueue.isEmpty()) {
result.add(videoQueue.poll());
}
/*不考虑adQueue为空的情况*/
/*videoQueue为空,adQueue还有的情况*/
if (currentSize >= maxInterval && !adQueue.isEmpty()) {//当前间隙大于最大间隙,则允许再插入一个ad
result.add(adQueue.poll());
}
return result;
}
/**
* 判断是否是video
* 我这只简单判断,根据名字关键字判断
*
* @param clip
* @return
*/
private boolean isVideo(String clip) {
if (clip.indexOf("video") != -1) {
return true;
}
return false;
}
public static void main(String[] args) {
List<String> list1 = new ArrayList<>();
List<String> list2 = new ArrayList<>();
list1.add("ad0");
list1.add("ad1");
list1.add("ad2");
list1.add("video0");
list1.add("video1");
list1.add("video2");
list1.add("video3");
list1.add("video4");
list2.add("video0");
list2.add("video1");
list2.add("video2");
list2.add("video4");
list2.add("video5");
list2.add("video6");
list2.add("ad0");
list2.add("ad1");
list2.add("video7");
List<String> result1 = new KanDianTest().getRecommendenResult(list1, 3);
List<String> result2 = new KanDianTest().getRecommendenResult(list2, 3);
System.out.println(result1);
System.out.println(result2);
/**
* [video0, video1, video2, ad0, video3, video4]
* [video0, video1, video2, video4, video5, video6, ad0, video7]
*/
}
}