background

When the List is a collection of basic data types, set operation is more convenient, but there are so few business scenarios, such as a user permission to the List of changes, or take the change of the data as a result, when sometimes stupid way cycle can be twice more, but the code is more complex, and the performance is not so good. This was the only requirement I encountered in this iteration.

implementation

Scene: Our users of the system are four dimensions of such data, we need to save the data, the front end are provided with an interface, the front passes the user the corresponding data (user group) | | | position department users, but the front can’t tell us, what is new, which is to remove, what did not change, anyway, all data to you, The back end organizes itself. Of course, the first thing I think of is a loop, but I usually put it as a last resort, and when I can’t think of a good one, I use the simplest one. And this place is based on the two fields in the entity class together, which adds complexity. List can be used to evaluate difference sets (similar to union sets) :

/ / difference set
List<String> subList = list1.stream().filter(item -> list2.contains(item)).collect(toList());
Copy the code

But this List is a String type, convenient, and we want to determine whether two objects are equal, simple, such as using, one thousand two objects that are not the same, such as a List of values from the database to retrieve, a coming, the field value is different, then they equals must be also different, The filtered values are also different, resulting in data errors.

// Consider filtering data without repeated updates
List<SaveLibUserParam> saveLibUserParamList = param.getSaveLibUserParamList();
List<UserCourseLibraryManage> originSaveList = Lists.newArrayList();
if (Objects.nonNull(saveLibUserParamList) && saveLibUserParamList.size() > 0) {
originSaveList = BeanConvertUtils.convertList(saveLibUserParamList, UserCourseLibraryManage.class);
}
// Query the original old data
List<UserCourseLibraryManage> list = userCourseLibraryManageDao.queryListByCompanyId(companyId);
log.info("originList:{}", originSaveList);
log.info("list:{}", list);
// List is not in origin
// If origin does not exist and list doesList<UserCourseLibraryManage> needAddList = originSaveList.stream().filter(item -> ! list.contains(item)).collect(Collectors.toList()); List<UserCourseLibraryManage> finalOriginSaveList = originSaveList; List<UserCourseLibraryManage> deleteList = list.stream().filter(item -> ! finalOriginSaveList.contains(item)).collect(Collectors.toList()); log.info("needAddList:size:{}, data:{}", needAddList.size(), needAddList);
log.info("deleteList:size:{}, data:{}", deleteList.size(), deleteList);
Copy the code

So let’s think about what equals equals equals equals equals equals equals equals equals equals equals equals equals equals equals equals equals equals equals equals equals equals equals equals equals equals equals equals equals equals equals equals equals Override equals (UserCourseLibraryManage); HashCode is also recommended to be overridden to ensure that two objects have the same hash value. The system determines that two objects are equal only if they have the same hash value. When rewriting hashcode, use 17. Use 17 in the Jdk.

/** * override equals method *@param obj
* @return* /
@Override
public boolean equals(Object obj) {
if (obj instanceof UserCourseLibraryManage) {
if (Objects.equals(((UserCourseLibraryManage) obj).dataType, this.dataType)
&& Objects.equals(((UserCourseLibraryManage) obj).dataId, this.dataId)) {
/ / System. Out. Println (" the same object: obj: "+ obj +", this: {} "+ this +" ");
return true;
} else {
return false; }}else {
return super.equals(obj); }}/** * rewrite hashcode *@return* /
@Override
public int hashCode(a) {
int newHashCode = dataType.hashCode();
newHashCode = 17 * newHashCode + dataId.hashCode();
return newHashCode;
}
Copy the code

After this processing, the filtered data is the data we want to achieve the purpose, and performance is definitely improved, using Java8 stream processing.

RemoveAll is also available from list. Stream. Take a look at the source code if you are interested, but removeAll changes the original data set.

I hope that if there are some friends who don’t know how to deal with this kind of problem in the future, I hope this sharing can be of some help!