现有如下左右两个表格,分别为材料和人员,需求内容为:
- 每份材料随机寻找3个人员来评阅,人员只能在本组内筛选,即11001号材料在第1组,就只能从第1组的人员中随机找3个人;
- 每个人不能评自己单位的材料,即在随机选人的时候,如果碰到材料和人员单位相同的情况就排除;
- 每一个人员评阅的材料份数要差不多一样,不能有的人特别多,有的人特别少;
- 匹配的结果以 :材料编号、人员编号1、人员编号2、人员编号3这样的格式输出。
我在处理的时候,将左右两个表格分别以Excel读取到集合中,然后遍历每一份材料,在材料对应的待选人员组中随机挑选3位进行评阅,但是最后无法处理每个人评的材料数量相差太多的情况,比如有的人评20份材料,有的人却只评3份材料。我的代码如下,请各位大神指教!
maven依赖如下:
<dependencies>
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-base</artifactId>
<version>4.2.0</version>
</dependency>
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-web</artifactId>
<version>4.2.0</version>
</dependency>
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-annotation</artifactId>
<version>4.2.0</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.10</version>
</dependency>
</dependencies>
材料实体类
public class ProjectVO {
@Excel(name = "项目编号")
private String code;
@Excel(name = "项目名称")
private String name;
@Excel(name = "责任单位")
private String unitName;
@Excel(name = "分组编号")
private String group;
//getter setter方法省略
}
人员实体类
public class UserVO {
@Excel(name = "手机号码")
private String userId;
@Excel(name = "专家姓名")
private String name;
@Excel(name = "工作单位")
private String unitName;
@Excel(name = "分组编号")
private String group;
private Integer count;
public UserVO() {
}
public UserVO(String userId, String name, String unitName, String group) {
this.userId = userId;
this.name = name;
this.unitName = unitName;
this.group = group;
}
//getter setter方法省略
}
随机匹配工具类
package com.eplugger;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import org.apache.commons.lang3.StringUtils;
import java.io.File;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
public class SelectUtil {
public void select(){
List<ProjectVO> proList = getProList();
Map<String,List<UserVO>> expMap = getExpList();
for (ProjectVO vo : proList){
//从人员组中取出待选的人员列表
List<UserVO> curExpList = expMap.get(vo.getGroup());
Set<UserVO> selectExps = randomExp(curExpList,5,vo);
System.out.println(selectExps.toString());
}
//打印每个人评了多少份材料
for(List<UserVO> list : expMap.values()){
for(UserVO user : list){
System.out.println(user.getName() + "\t" + user.getCount());
}
}
}
public static void main(String[] args) {
new SelectUtil().select();
}
public List<ProjectVO> getProList(){
File file = new File("材料分组.xlsx");
ImportParams params = new ImportParams();
params.setHeadRows(1);
List<ProjectVO> infos = ExcelImportUtil.importExcel(file, ProjectVO.class, params);
return infos;
}
public Map<String,List<UserVO>> getExpList(){
File file = new File("人员分组.xlsx");
ImportParams params = new ImportParams();
params.setHeadRows(1);
List<UserVO> infos = ExcelImportUtil.importExcel(file, UserVO.class, params);
Map<String, List<UserVO>> map = infos.stream().collect(Collectors.groupingBy(UserVO::getGroup));
return map;
}
/**
* 功能:随机指定范围内N个不重复的数
*
* @param n 随机数个数
*/
public static Set<UserVO> randomExp(List<UserVO> eList, int n,ProjectVO pVO) {
Set<UserVO> set = new HashSet<>();
for (; true;) {
// 调用Math.random()方法
int num = (int) (Math.random() * (eList.size() - 0)) + 0;
UserVO userVO = eList.get(num);
// 将不同的数存入HashSet中
if (!StringUtils.equals(userVO.getUnitName(),pVO.getUnitName())){
if(userVO.getCount() == null){
set.add(userVO);
userVO.setCount(1);
}else {
set.add(userVO);
userVO.setCount(userVO.getCount() + 1);
}
}
// 如果存入的数小于指定生成的个数,则调用递归再生成剩余个数的随机数,如此循环,直到达到指定大小
if (set.size() >= n) {
break;
}
}
return set;
}
}