如何对serviceNeedingTasks集合按对象属性及属性乘积排序?
关于ArrayList多属性排序的问题解答
1. 如何对serviceNeedingTasks按对象的两个属性进行排序?
要实现按两个属性排序,核心是通过自定义Comparator来控制排序优先级:
- 先以第一个属性作为主要排序依据,如果两个对象在该属性上有差异,直接返回比较结果;
- 若第一个属性完全相等,再以第二个属性作为次要排序依据,返回最终的排序结果。
举个具体例子:假设我们想先按p_t升序排序,当p_t相同时再按weight降序排序,代码可以这样写:
Collections.sort(serviceNeedingTasks, new Comparator<Tasks>() { @Override public int compare(Tasks c1, Tasks c2) { // 先比较p_t(升序) int ptCompare = Integer.compare(c1.p_t, c2.p_t); if (ptCompare != 0) { return ptCompare; } // p_t相等时,比较weight(降序) return Integer.compare(c2.weight, c1.weight); } });
如果是Java 8及以上版本,还能用更简洁的Lambda表达式实现:
serviceNeedingTasks.sort(Comparator.comparingInt(Tasks::getP_t) .thenComparingInt(Tasks::getWeight).reversed());
2. 修正按p_t * weight乘积排序的代码
你当前的代码确实存在一个低级错误——在比较第二个对象的乘积时,误用了c1.weight代替c2.weight,这直接导致排序逻辑完全失效。
错误代码分析
Collections.sort(serviceNeedingTasks, new Comparator<Tasks>() { public int compare(Tasks c1, Tasks c2) { if ((c1.p_t)*(c1.weight) > (c2.p_t)*(c1.weight)) return -1; if ((c1.p_t)*(c1.weight) < (c2.p_t)*(c1.weight)) return 1; return 0; } });
这里的第二个判断条件里,你错误地使用了c1.weight来计算第二个对象的乘积,正确的应该是c2.weight。
修正后的代码
另外,为了避免整数溢出(如果p_t和weight是较大的整数),建议用Long类型存储乘积结果:
Collections.sort(serviceNeedingTasks, new Comparator<Tasks>() { @Override public int compare(Tasks c1, Tasks c2) { long product1 = (long) c1.p_t * c1.weight; long product2 = (long) c2.p_t * c2.weight; // 这里是降序排序,如果需要升序,改成return Long.compare(product1, product2)即可 return Long.compare(product2, product1); } });
Java 8+也可以用Lambda简化成这样:
serviceNeedingTasks.sort((c1, c2) -> { long product1 = (long) c1.p_t * c1.weight; long product2 = (long) c2.p_t * c2.weight; return Long.compare(product2, product1); });
这样就能正确按照p_t与weight的乘积完成排序了~
内容的提问来源于stack exchange,提问作者sorour
相关产品推荐
相关产品推荐

