[英]Java Stream Sort - Comparator with 2 or more Criteria for Objects
[英]Sort the Objects with comparator logic in java
我正在尝试使用以下参数对对象列表进行排序
a.group两个列表对象,其partId与其他对象的id相同
b。 将partId为null的任何对象推到列表的末尾。
C。 根据计数以升序对分组的对象进行排序,首选是
I.组中的两个对象都应减少计数
二。 那么组中的任何对象的计数都比其他组少。
以下是我到目前为止的代码,
public class ListTTest {
public static void main(String[] args) {
LstObj lstObj1 = new LstObj("0:0:1", "1:0:1", 49);
LstObj lstObj2 = new LstObj("0:0:2", "1:0:2", 2);
LstObj lstObj3 = new LstObj("0:2:1", "1:2:1", 0);
LstObj lstObj4 = new LstObj("0:2:2", null , 0);
LstObj lstObj5 = new LstObj("0:2:3", "1:2:3" , 2);
LstObj lstObj6 = new LstObj("0:2:4", "1:2:4" , 49);
LstObj lstObj7 = new LstObj("1:0:1", "0:0:1" , 49);
LstObj lstObj8 = new LstObj("1:0:2", "0:0:2" , 49);
LstObj lstObj9 = new LstObj("1:2:1", "0:2:1" , 0);
LstObj lstObj10 = new LstObj("1:2:2", null , 0);
LstObj lstObj11 = new LstObj("1:2:3", "0:2:3" , 49);
LstObj lstObj12 = new LstObj("1:2:4", "0:2:4" , 49);
LstObj lst[] = new LstObj[]{lstObj1,lstObj2,lstObj3,lstObj4,lstObj5,lstObj6,lstObj7,lstObj8,lstObj9,lstObj10,lstObj11,lstObj12};
List<LstObj> lstArr = Arrays.asList(lst);
lstArr.sort(new Comparator<LstObj>() {
@Override
public int compare(LstObj o1, LstObj o2) {
if(o1.partId==null){
return 1;
}else if(o2.partId==null){
return -1;
}else{
return -1*(o1.partId.compareTo(o2.id)-(o1.count-o2.count));
}
}
});
System.out.println(lstArr);
}
}
class LstObj {
String partId;
String id;
int count;
public LstObj( String id,
String partId,
int count
) {
this.count = count;
this.partId = partId;
this.id = id;
}
public String getPartId() {
return partId;
}
public String getId() {
return id;
}
public int getCount() {
return count;
}
public void setPartId(String partId) {
this.partId = partId;
}
public void setId(String id) {
this.id = id;
}
public void setCount(int count) {
this.count = count;
}
@Override
public String toString() {
return "LstObj [partId=" + partId + ", id=" + id + ", count=" + count
+ "]\n";
}
}
上面代码的输出是:
[LstObj [partId=1:2:1, id=0:2:1, count=0]
, LstObj [partId=1:2:3, id=0:2:3, count=2]
, LstObj [partId=0:2:1, id=1:2:1, count=0]
, LstObj [partId=1:0:2, id=0:0:2, count=2]
, LstObj [partId=1:2:4, id=0:2:4, count=49]
, LstObj [partId=0:2:3, id=1:2:3, count=49]
, LstObj [partId=1:0:1, id=0:0:1, count=49]
, LstObj [partId=0:0:1, id=1:0:1, count=49]
, LstObj [partId=0:0:2, id=1:0:2, count=49]
, LstObj [partId=0:2:4, id=1:2:4, count=49]
, LstObj [partId=null, id=0:2:2, count=0]
, LstObj [partId=null, id=1:2:2, count=0]
但我正在寻找输出为:
[LstObj [partId=0:2:1, id=1:2:1, count=0]
, LstObj [partId=1:2:1, id=0:2:1, count=0]
, LstObj [partId=0:0:2, id=1:0:2, count=2]
, LstObj [partId=1:0:2, id=0:0:2, count=49]
, LstObj [partId=0:2:3, id=1:2:3, count=2]
, LstObj [partId=1:2:3, id=0:2:3, count=49]
, LstObj [partId=0:0:1, id=1:0:1, count=49]
, LstObj [partId=1:0:1, id=0:0:1, count=49]
, LstObj [partId=0:2:4, id=1:2:4, count=49]
, LstObj [partId=1:2:4, id=0:2:4, count=49]
, LstObj [partId=null, id=0:2:2, count=0]
, LstObj [partId=null, id=1:2:2, count=0]
有人知道我到底在哪里做错吗?
仅仅通过查看列表中的两个元素,就不可能实现应用您期望的分组逻辑的比较器。
您可以执行专门的分组操作并对分组进行排序,然后再创建结果列表。 内置分组收集器需要一个功能,该功能能够将每个元素分配给一个组而不会看到对应的对象,但是如果您使用稳定的选择器(例如,使用partId
和id
的最小值),则正确的元素将partId
为一组,例如只要您输入的数据具有正确的形状。
List<LstObj> lstArr = Arrays.asList(
new LstObj("0:0:1", "1:0:1", 49),
new LstObj("0:0:2", "1:0:2", 2),
new LstObj("0:2:1", "1:2:1", 0),
new LstObj("0:2:2", null , 0),
new LstObj("0:2:3", "1:2:3" , 2),
new LstObj("0:2:4", "1:2:4" , 49),
new LstObj("1:0:1", "0:0:1" , 49),
new LstObj("1:0:2", "0:0:2" , 49),
new LstObj("1:2:1", "0:2:1" , 0),
new LstObj("1:2:2", null , 0),
new LstObj("1:2:3", "0:2:3" , 49),
new LstObj("1:2:4", "0:2:4" , 49)
);
Function<LstObj,Object> groupFunc = o -> {
String id = o.getId(), partId = o.getPartId();
return partId == null? Void.TYPE: partId.compareTo(id)<0? partId: id;
};
List<LstObj> result = lstArr.stream()
.sorted(Comparator.comparing(LstObj::getPartId, Comparator.nullsLast(null))
.thenComparingInt(LstObj::getCount))
.collect(Collectors.groupingBy(groupFunc, LinkedHashMap::new, Collectors.toList()))
.values().stream()
.flatMap(List::stream)
.collect(Collectors.toList());
System.out.println(result);
这partId
所有元素进行排序,将partId
为null
所有对象移动到列表的末尾,并按计数作为第二顺序进行排序。 随后的分组操作使用LinkedHashMap
,该LinkedHashMap
保留了遇到的顺序,并根据它们的第一个遇到的元素(具有最小计数的元素)有效地对这些组进行了排序。 然后将这些组展平到结果列表。
结果满足指定的问题标准,但由于组中元素的顺序未指定,因此不能完全生成您按期望结果发布的列表。 上面的代码按计数对它们进行排序,这是初始排序的副作用,并保留具有相同计数的元素的原始列表顺序。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.