[英]Java - Optimise Comparator operation to sort a list of POJO
I'm writing a Comparator
for one of my DTO.我正在为我的一个 DTO 编写一个Comparator
器。
Each DTO object MyDTO
contains a Set of Themes
.每个 DTO object MyDTO
包含一组Themes
。
class MyDTO {
Long id;
Set<Theme> themes;
}
class ThemeDTO {
Long id;
String title;
}
We've a given list of themeIDs as input, say Set<Long> inputThemes
against which we've to make a comparison and sort list of MyDTOs.我们有一个给定的主题 ID 列表作为输入,比如Set<Long> inputThemes
,我们必须根据它对 MyDTO 的列表进行比较和排序。
Logic for comparison is:比较的逻辑是:
I've written below comparator, but feels like it can be optimised further.我在比较器下面写过,但感觉可以进一步优化。
myDTOList.sort(new Comparator<MyDTO>() {
@Override
public int compare(MyDTO o1, MyDTO o2) {
Set<Long> o1ThemeSet = o1.getThemes().stream().map(ThemeDTO::getId).collect(toSet());
Set<Long> o2ThemeSet = o2.getThemes().stream().map(ThemeDTO::getId).collect(toSet());
// Filtering w.r.t to themes coming as input
Set<Long> inputThemeSet = inputThemes.stream().collect(toSet());
o1ThemeSet.retainAll(inputThemeSet);
o2ThemeSet.retainAll(inputThemeSet);
if (o1ThemeSet.size() == o2ThemeSet.size()) {
// If 2 MyDTO have same number of theme matches, sorting is done alphabetically.
return o1.getTitle().toLowerCase().compareTo(o2.getTitle().toLowerCase());
} else if (o1ThemeSet.size() < o2ThemeSet.size()) {
return 1;
} else {
return -1;
}
}
});
Create a map for MyDTO list where store MyDTO#id as key and matched themes as value为 MyDTO 列表创建一个 map,其中将 MyDTO#id 存储为键,将匹配的主题存储为值
Set<Long> inputThemeSet = inputThemes.stream().collect(toSet());
Map<Long, Integer> map = new HashMap<>();
myDTOList.forEach(e -> {
Integer cnt = (int)e.getThemes().stream().filter(k -> inputThemeSet.contains(k.getId())).count();
map.put(e.getId(), cnt);
});
Then you can sort, here optimization is for same MyDTO you don't need to do upper operation for every two comparison MyDTO object.然后就可以排序了,这里优化的是同一个MyDTO,不需要对每两个比较MyDTO object做上层操作。 Number of comparison is huge bigger than list size.比较的数量比列表大小大得多。
myDTOList.sort(new Comparator<MyDTO>() {
@Override
public int compare(MyDTO o1, MyDTO o2) {
if (map.get(o1.getId()) == map.get(o2.getId())) {
return o1.getTitle().toLowerCase().compareTo(o2.getTitle().toLowerCase());
}
return (map.get(o1.getId()) < map.get(o2.getId())) ? 1 : -1;
}
});
Note: The code is untested hope you get the idea注意:代码未经测试希望你明白
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.