java中复杂业务情况下的集合操作(增减集合同步数据)

Posted 穆雄雄

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java中复杂业务情况下的集合操作(增减集合同步数据)相关的知识,希望对你有一定的参考价值。

大家好,我是雄雄,欢迎关注微信公众号:雄雄的小课堂

现在是:2022年7月5日16:14:28

前言

今天分享个案例,需求是这样的:一个团组中是可以包含多个会员,在给团组创建训练方案时,本质上是给每个会员分别制定了一套训练方案。那么会有个问题,比如创建一个团组A,里面有会员1,会员2,会员3,然后给团组A创建了个方案,那么对应的三个会员都有训练方案,此时,将会员4拉到团组A中,此时会员4是没有任何方案的,所以我们现在要做的就是将会员4也同步上团组A的方案。

思路

在给团组新建完方案之后,通过团组管理是可以对该团组中的成员增加或者减少的,就像微信群聊一样,既可以重新邀人,也可以踢人出去。只是我们的业务里面加入了方案的概念。

新加的人就需要同步训练方案,删除的人就需要删掉他的方案,这个地方我是这样处理的:

  1. 通过java中集合的方法,找出哪些是新加的人,哪些是减去的人。
  2. 将团组和两个集合(新加的人的集合和减少的人的集合)传入到处理方案的方法中去操作
  3. 涉及到两个系统,一个是我方系统,一个是训练方案系统,并且都是我写的,所以接口操作起来就比较方便。

具体代码

团组管理

		/**
	 * 修改团组 团组里面编辑成员时,更新对应的训练方案
	 */
	@PostMapping("/updateGroup")
	@ApiOperationSupport(order = 2)
	@ApiOperation(value = "app-新增团组", notes = "传入teamGroup")
	public R updateGroup(@RequestBody TeamGroup teamGroup) 
		//1.先把原来的人放在一个集合中
		List<Long> userListOld = new ArrayList<>();
		LambdaQueryWrapper<GroupUser> groupUserLambdaQueryWrapper = new LambdaQueryWrapper<>();
		groupUserLambdaQueryWrapper.eq(GroupUser::getGroupId, teamGroup.getId());
		//集合去重
		List<GroupUser> groupUserList =
			groupUserService
				.list(groupUserLambdaQueryWrapper)
				.stream()
				.distinct()
				.collect(Collectors.toList());
		for (GroupUser groupUser : groupUserList) 
			//将原来的用户添加到这个集合中
			userListOld.add(groupUser.getUserId());
		
		//拿到人员集合,把关联表中的数据,根据团组id把之前的数据都删掉,
		//然后再重新添加新获得的人员集合.
		groupUserService.remove(groupUserLambdaQueryWrapper);
		//2.将新更新过来的人放在一个集合中
		List<Long> userListNew = new ArrayList<>();
		if (teamGroup.getUserIds() != null && !"".equals(teamGroup.getUserIds())) 
			userListNew = CommonUtil.transLongList(teamGroup.getUserIds());
			//设置团组人数
			teamGroup.setNumPeople(userListNew.size());
			//把人员和团组在关联表中维护起来.
			for (int i = 0; i < userListNew.size(); i++) 
				GroupUser groupUser = new GroupUser();
				groupUser.setGroupId(teamGroup.getId());
				User user = userService.getUserById(userListNew.get(i));
				groupUser.setUserId(user.getId());
				groupUser.setUserName(user.getName());
				groupUser.setIsDeleted(0);
				groupUserService.save(groupUser);
			
		
		//3.两个集合比较哪些是新增的,哪些是删除的
		//新增的会员
		List<Long> userListAdd = new ArrayList<>(userListNew);
		userListAdd.removeAll(userListOld);
		//输出集合中的元素
		System.out.println("新增了的会员:");
		userListAdd.forEach(System.out::println);
		//删除了的会员
		List<Long> userListDel = new ArrayList<>(userListOld);
		userListDel.removeAll(userListNew);
		//输出集合中的元素
		System.out.println("删除了的会员:");
		userListDel.forEach(System.out::println);
		//传给训练方案系统,团组id,要删除的会员集合,要新增的会员集合--2022年7月5日13:56:15 updateer:穆雄雄
		R r = trainingSchemeUrlService.updateProgrammeByGroupIdAndOldUserIdAndNewUserId(teamGroup.getId(),userListAdd,userListDel);
		if(r.getCode()!=200)
			return R.fail("同步团组训练方案失败");
		
		//更新团组的基础信息
		return R.status(teamGroupService.updateById(teamGroup));
	

代码中基本都有注释,下面我来分析一下关键的代码,比较两个集合中哪些是新增的,哪些是删除的?

	//新增的会员
		List<Long> userListAdd = new ArrayList<>(userListNew);
		userListAdd.removeAll(userListOld);
		//输出集合中的元素
		System.out.println("新增了的会员:");
		userListAdd.forEach(System.out::println);
		//删除了的会员
		List<Long> userListDel = new ArrayList<>(userListOld);
		userListDel.removeAll(userListNew);
		//输出集合中的元素
		System.out.println("删除了的会员:");
		userListDel.forEach(System.out::println);

接下来就是在本系统中调用训练方案系统的同步方案接口了,具体代码如下:

Service接口层:

		/**
	 * 团组更新成员时,方案也跟着同步
	 * @param
	 * @param
	 * @param
	 * @return
	 */
	R  updateProgrammeByGroupIdAndOldUserIdAndNewUserId(Long groupId, List<Long> userListAdd, List<Long>userListDel);

ServiceImpl实现类:

	@Override
	public R updateProgrammeByGroupIdAndOldUserIdAndNewUserId(Long groupId, List<Long> userListAdd, List<Long> userListDel) 
		//请求接口地址
		String url = TrainingSchemeConstant.updateProgrammeByGroupIdAndOldUserIdAndNewUserId;
		JSONObject jsonObject = new JSONObject();
		jsonObject.putOpt("groupId", groupId);
		jsonObject.putOpt("userListAdd", userListAdd);
		jsonObject.putOpt("userListDel", userListDel);
		try 
			String body = HttpRequest.post(url)
				.header("Content-Type", "application/json")
				.body(jsonObject.toString())
				.execute().body();
			if (StringUtils.isBlank(body)) 
				return R.fail("操作失败");
			
			JSONObject obj = JSONUtil.parseObj(body);
			if (obj == null) 
				return R.fail("操作失败");
			
			String code = obj.get("code").toString();
			if ("200".equals(code)) 
				return R.success("操作成功");
			
		 catch (Exception e) 
			e.printStackTrace();
		
		return null;
	

接口地址工具类:

	/**
		 * 根据会员Id 状态 时间,查询所有动作
		 */
		public String updateProgrammeByGroupIdAndOldUserIdAndNewUserId = TRAINING_PROGRAMME+"/api/trainingprogramev3/updateProgrammeByGroupIdAndOldUserIdAndNewUserId";

训练方案系统中同步团组方案

	/**
	 * 根据团组id,新老用户的id编辑方案
	 * 2022年5月31日22:16:01
	 * 穆雄雄
	 *
	 * @return
	 */
	@PostMapping(value = "/updateProgrammeByGroupIdAndOldUserIdAndNewUserId")
	public String updateProgrammeByGroupIdAndOldUserIdAndNewUserId(@RequestBody GroupUpdateUser groupUpdateUser) 
		JSONObject jsonObject = new JSONObject();
		if (groupUpdateUser.getGroupId() == null) 
			jsonObject.put("code", 500);
			jsonObject.put("success", false);
			jsonObject.put("msg", "团组id不能为空");
		
		//先从redis里面取一下,如果redis里面没有的话,就执行下面的内容
		Map<String, Object> programmeMap = bladeRedis.get("createGroupProgramme:" + groupUpdateUser.getGroupId());
		System.out.println("团组在编辑会员的时候,redis中的数据是:" + programmeMap);
		Programme programme = null;
		TeamGroup teamGroup = null;
		//方案的集合
		List<Programme> programmeList = new ArrayList<>();
		//时间戳
		Long timechuo = null;
		//缓存里面没有
		QueryWrapper<TeamGroup> teamGroupQueryWrapper = new QueryWrapper<>();
		teamGroupQueryWrapper.eq("group_id", groupUpdateUser.getGroupId()).orderByDesc("id").last("limit 1");
		teamGroup = teamGroupService.getOne(teamGroupQueryWrapper);
		//判断如果缓存里面没有的话,查询一下实际的
		if (programmeMap == null) 
			//没有方案的话
			if (teamGroup == null) 
				jsonObject.put("code", 200);
				jsonObject.put("success", true);
				jsonObject.put("msg", "操作成功");
				return jsonObject.toJSONString();
			
			//将peibeizhu的值修改一下
			//根据方案的id查询出来方案信息
			programme = programmeService.getById(teamGroup.getProgrammeId());
			timechuo = programme.getTimechuo();
			System.out.println("编辑方案时,redis缓存里面没有数据");
		else
			//获取缓存中的时间戳
			timechuo = (Long) programmeMap.get("timechuo");
			System.out.println("编辑方案时,redis缓存里面有数据");
		


		//aid的集合,最后放在pbeizhu里面去
		List<Long> pBeiZhuAidList = new ArrayList<>();
		//根据时间戳查询出所有方案
		LambdaQueryWrapper<Programme> programmeLambdaQueryWrapper = new LambdaQueryWrapper<>();
		programmeLambdaQueryWrapper.eq(Programme::getTimechuo, timechuo);
		List<Programme> programmeListByTimeChuo = programmeService.list(programmeLambdaQueryWrapper);
		programmeListByTimeChuo.forEach(pro -> 
			//重新赋值pbeizhu的值
			pBeiZhuAidList.add(pro.getPaid());
			programmeList.add(pro);
		);

		//运动员主键id集合
		List<Long> aidList = new ArrayList<>();
		//同步一下新加的用户信息
		if (groupUpdateUser.getUserListAdd().size() > 0) 
			for (Long aid : groupUpdateUser.getUserListAdd()) 
				Athletes athletes = new Athletes();
				LambdaQueryWrapper<Athletes> athletesLambdaQueryWrapper = new LambdaQueryWrapper<>();
				athletesLambdaQueryWrapper.eq(Athletes::getWorkcode, aid);
				List<Athletes> athleteList = athletesService.list(athletesLambdaQueryWrapper);
				if (athleteList.size() > 0) 
					//找到了
					athletes = athleteList.get(0);
				 else 
					//没有找到
					athletes.setAname(aid.toString());
					athletes.setWorkcode(aid.toString());
					athletesService.save(athletes);
				
				aidList.add(athletes.getId());
			

		
		//加上了的成员
		for (Long aid : aidList) 
			//根据时间戳和用户id查询方案,有则添加,无则不用
			LambdaQueryWrapper<Programme> programmeWrapper = new LambdaQueryWrapper<>();
			programmeWrapper
				.eq(Programme::getPaid, aid)
				.eq(Programme::getTimechuo, timechuo)
				.last("limit 1");
			List<Programme> programmeQueryList = programmeService.list(programmeWrapper);
			if (programmeQueryList.size() == 0) 
				if(programme==null)
					programme = programmeList.get(0);
				
				//远动员主键
				programme.setPaid(aid);
				//是否是团组方案 0是 1 不是
				programme.setIsGroupProgramme(0);
				//给用户保存方案
				programmeService.save(programme);
			
		

		//将运动员的主键拿到放在集合里面(删除方案)--暂时先不删除了。因为怕误删掉个人的方案 2022年7月4日21:23:19
		if (groupUpdateUser.getUserListDel().size() > 0) 
			//删除了的成员
			for (Long uid : groupUpdateUser.getUserListDel()) 
				//去运动员表卡里面查询这个人的编号
				LambdaQueryWrapper<Athletes> athletesLambdaQueryWrapper = new LambdaQueryWrapper<>();
				athletesLambdaQueryWrapper.select(Athletes::getId)
					.eq(Athletes::getWorkcode, uid)
					.last("limit 1");
				Athletes athletes = athletesService.getOne(athletesLambdaQueryWrapper);
				if (athletes != null) 
					//(遗留了bug,如果这个人正好是这个团组的最后一个方案的话,删掉之后,会导致团组和方案关联表中的方案id在方案里面找不到)
					//将方案表中的paid是这个人的都删掉
					Map<String, Object> map = new HashMap<>();
					map.put("paid", athletes.getId());
					map.put("timechuo", programme.getTimechuo());
					//map.put("is_group_programme",0);
					//物理删除
					programmeService.delProgrammeByAid(map);
				
			
		


		//把集合中的
		String pbeizhu = StringUtils.join(pBeiZhuAidList, ",");
		programmeListByTimeChuo.forEach(pro -> 
			//重新赋值pbeizhu的值
			pro.setPbeizhu(pbeizhu);
			//修改pbiezhu的信息
			programmeService.updateById(pro

以上是关于java中复杂业务情况下的集合操作(增减集合同步数据)的主要内容,如果未能解决你的问题,请参考以下文章

JAVA几个集合使用情况

在Java中将字符串集合复制到另一个字符串的时间复杂度

Java多线程与并发库高级应用-同步集合

集合(上)

Java中的集合都有哪些 在啥情况下使用

Java Collection接口下的“ List 集合” 与 “ Set 集合 ”