简体   繁体   English

使用Java中的比较器逻辑对对象进行排序

[英]Sort the Objects with comparator logic in java

I am trying to sort the list of objects with following parameters 我正在尝试使用以下参数对对象列表进行排序

a.group the two list objects whose partId is same as id of other object a.group两个列表对象,其partId与其他对象的id相同

b. b。 Push any object whose partId is null to the end of the list. 将partId为null的任何对象推到列表的末尾。

c. C。 sort the grouped objects based on the count in ascending order, preference is to 根据计数以升序对分组的对象进行排序,首选是

I. both the objects in the group should have less count I.组中的两个对象都应减少计数

II. 二。 then any object in group having less count than other groups. 那么组中的任何对象的计数都比其他组少。

Below is the code I have so far, 以下是我到目前为止的代码,

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";
    }


}

Output for above code is : 上面代码的输出是:

[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]

But I am looking for output as: 但我正在寻找输出为:

 [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]

Anybody have any idea where exactly I'm doing wrong? 有人知道我到底在哪里做错吗?

It is impossible to implement a comparator applying your intended grouping logic by just looking at two elements of the list. 仅仅通过查看列表中的两个元素,就不可能实现应用您期望的分组逻辑的比较器。

You may perform a dedicated grouping operation and sort the groups, followed by creating a result list afterwards. 您可以执行专门的分组操作并对分组进行排序,然后再创建结果列表。 The builtin grouping collector requires a function that is capable of assigning each element to a group without seeing the counterpart, but if you use a stable selector, eg using the minimum of partId and id , the correct elements will end up in one group, as long as your input data has the right shape. 内置分组收集器需要一个功能,该功能能够将每个元素分配给一个组而不会看到对应的对象,但是如果您使用稳定的选择器(例如,使用partIdid的最小值),则正确的元素将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);

This sorts all elements, moving all objects whose partId is null to the end of the list and sorting by count as secondary order. partId所有元素进行排序,将partIdnull所有对象移动到列表的末尾,并按计数作为第二顺序进行排序。 The subsequent grouping operation uses a LinkedHashMap which retains the encounter order, effectively sorting the groups according to their first encountered element, which is the one with the minimum count. 随后的分组操作使用LinkedHashMap ,该LinkedHashMap保留了遇到的顺序,并根据它们的第一个遇到的元素(具有最小计数的元素)有效地对这些组进行了排序。 The groups are then flattened to a result list. 然后将这些组展平到结果列表。

The result fulfills the specified criteria of your question but does not exactly produce the list you have posted as desired result, as the order of the elements within the groups is underspecified. 结果满足指定的问题标准,但由于组中元素的顺序未指定,因此不能完全生成您按期望结果发布的列表。 The code above sorts them by count, as a side effect of initial sorting, and keeps the original list order for elements with the same count. 上面的代码按计数对它们进行排序,这是初始排序的副作用,并保留具有相同计数的元素的原始列表顺序。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM