为了账号安全,请及时绑定邮箱和手机立即绑定

基于java中的嵌套值对对象列表进行排序

基于java中的嵌套值对对象列表进行排序

猛跑小猪 2023-10-13 10:28:33
我有一个计划在多个日期交付的汽车列表,需要根据以下几点进行排序:如果isReady>0,那么它应该首先显示在表中。然后该特定日期的其他值低于它。如果isReady>0和对象gear!=null那么,它首先显示在该特定日期的表中。接下来是 Object 所在的其他值gear==null。如果isReady>0、 Objectgear!=null和 Object tyre!=null,则该值将首先显示在该特定日期的表中。接下来是其他值,其中 Objectgear==null和tyre==null.以下是class代码:public class Car {    private int isReady;    private Tyre tyre;    private Gear gear;    private Date deliveryDate;}public class Gear {    private int id;    private String type;}public class Tyre {    private int id;    private String grip;}public class CarComparator implements Comparator<Car> {    @Override    public int compare(Car entry1, Car entry2) {        int value = 0;        if (entry1.getIsReady() > entry2.getIsReady()) {            value = -1;        } else if (entry1.getIsReady() < entry2.getIsReady()) {            value = 1;        } else if (entry1.getIsReady() == entry2.getIsReady()) {            value = 0;        }        return value;    }}我开发了一个比较器,它适用于第一个条件 where isReady>0。您能帮我解决上述其他条件吗?提前致谢。
查看完整描述

4 回答

?
梵蒂冈之花

TA贡献1900条经验 获得超5个赞

好吧,从 Java 8 开始,您可以像这样构建比较器:


//order by delivery date first, ascending order

Comparator<Car> carComparator = Comparator.comparing( Car::getDeliveryDate )

  //order by isReady in ascending order

  .thenComparing( Car::getIsReady )

  //we map null to 1 and non-null to -1 and ignore the rest for now

  .thenComparing( car -> car.getGear() != null ? -1 : 1 ) 

  .thenComparing( car -> car.getTyre() != null ? -1 : 1 );


查看完整回答
反对 回复 2023-10-13
?
慕桂英546537

TA贡献1848条经验 获得超10个赞

检查此比较器,以便您可以使用多个属性进行排序


public class CarComparator implements Comparator<Car> {


    @Override

    public int compare(Car entry1, Car entry2) {

        int value;

        if (entry1.getDeliveryDate().before(entry2.getDeliveryDate())){

            value = -1;

        }else if (entry1.getDeliveryDate().equals(entry2.getDeliveryDate())){

            value = 0;

        }else{

            value =1;

        }

        //For same day

        if (value==0){

            if (entry1.getIsReady() > entry2.getIsReady()) {

                value = -1;

            } else if (entry1.getIsReady() < entry2.getIsReady()) {

                value = 1;

            } else if (entry1.getIsReady() == entry2.getIsReady()) {

                value = 0;

            }

        }

        //if same isReady

        if (value==0){

            if (entry1.getGear()!=null && entry2.getGear()==null) {

                value = -1;

            } else  if (entry1.getGear()==null && entry2.getGear()==null) {

                value = 0;

            } else{

                value = 1;

            }

        }

        //if still equals

        if (value==0){

            if (entry1.getTyre()!=null && entry2.getTyre()==null) {

                value = -1;

            } else  if (entry1.getTyre()==null && entry2.getTyre()==null) {

                value = 0;

            } else{

                value = 1;

            }

        }



        return value;

    }

}

我不确定这是否是您尝试做的。上面的比较器的作用是:首先对日期进行排序,如果找到相等的日期(值=0),则比较 isReady,然后比较 getGear(),最后比较 getTyre()。


这样您就可以在比较器中添加所需数量的属性。


包括3辆车的主要方法


public class Main {

    public static void main (String[]args) throws UnsupportedEncodingException, ParseException {


        List<Car> carL = new ArrayList<Car>();


        Car car1 = new Car();

        car1.setDeliveryDate(new Date());

        Gear gear1 = new Gear();

        car1.setGear(gear1);

        Tyre tyre1 = new Tyre();

        car1.setTyre(null);

        car1.setId(1);

        car1.setDeliveryDate((new SimpleDateFormat("dd-MM-yyyy")).parse("01-01-2000"));

        car1.setIsReady(0);


        Car car2 = new Car();

        car2.setDeliveryDate(new Date());

        Gear gear2 = new Gear();

        car2.setGear(gear2);

        Tyre tyre2 = new Tyre();

        car2.setTyre(tyre2);

        car2.setId(2);

        car2.setDeliveryDate((new SimpleDateFormat("dd-MM-yyyy")).parse("02-01-2000"));


        car2.setIsReady(1);


        Car car3 = new Car();

        car3.setDeliveryDate(new Date());

        Gear gear3 = new Gear();

        car3.setGear(gear3);

        Tyre tyre3 = new Tyre();

        car3.setTyre(tyre3);

        car3.setId(3);

        car3.setDeliveryDate((new SimpleDateFormat("dd-MM-yyyy")).parse("01-01-2000"));


        car3.setIsReady(1);


        carL.add(car1);

        carL.add(car2);

        carL.add(car3);

        Collections.sort(carL, new CarComparator());

        for (Car car : carL) {

            System.out.println("car: " + car.toString());

        }

    }

}

输出:


car: Car{id=3, isReady=1, tyre=false, gear=false, deliveryDate=Sat Jan 01 00:00:00 EET 2000}

car: Car{id=1, isReady=0, tyre=true, gear=false, deliveryDate=Sat Jan 01 00:00:00 EET 2000}

car: Car{id=2, isReady=1, tyre=false, gear=false, deliveryDate=Sun Jan 02 00:00:00 EET 2000}



查看完整回答
反对 回复 2023-10-13
?
弑天下

TA贡献1818条经验 获得超8个赞

为什么不重用 Integer.compareTo 来使代码更短?


像这样:


import java.util.Comparator;


public class CarComparator implements Comparator<Car> {

    @Override

    public int compare(Car entry1, Car entry2) {

        int value = 0;


        // might want to add a null check for either entry1 and entry2


        value = entry1.getDeliveryDate().compareTo(entry2.getDeliveryDate());

        if (value == 0) {

            value = ((Integer)entry1.getIsReady()).compareTo((Integer)entry2.getIsReady());

            if (value == 0) {

                value = getIntegerValueForNullCheck(entry1.getGear()).compareTo(getIntegerValueForNullCheck(entry2.getGear()));

                if (value == 0) {

                    value = getIntegerValueForNullCheck(entry1.getTyre()).compareTo(getIntegerValueForNullCheck(entry2.getTyre()));

                }

            }

        }


        return value;

    }

    private Integer getIntegerValueForNullCheck (Object o) {

        return o == null ? 0 : 1;

    }

}

包括测试排序的代码:


import java.time.Duration;

import java.time.Instant;

import java.time.LocalDateTime;

import java.util.*;


public class Sorting {


    public static void main(String[] args) {


        List<Car> cars = new LinkedList<>();



        Date today = new Date();

        Instant now = Instant.now();

        Instant after = now.plus(Duration.ofDays(1));

        Date tomorrow = Date.from(after);


        cars.add(new Car(5, new Tyre(1,"1"), new Gear(1, "1"), today ));

        cars.add(new Car(5, new Tyre(1,"1"), null, today ));

        cars.add(new Car(5, null, null, today ));

        cars.add(new Car(4, null, null, today ));

        cars.add(new Car(3, null, null, tomorrow ));



        Collections.sort(cars, new CarComparator());

        System.out.println(cars);

    }


}

输出:


[Car{isReady=4, tyre=null, gear=null, deliveryDate=Thu Oct 10 11:27:20 IDT 2019}

, Car{isReady=5, tyre=null, gear=null, deliveryDate=Thu Oct 10 11:27:20 IDT 2019}

, Car{isReady=5, tyre=Tyre{id=1, grip='1'}, gear=null, deliveryDate=Thu Oct 10 11:27:20 IDT 2019}

, Car{isReady=5, tyre=Tyre{id=1, grip='1'}, gear=Gear{id=1, type='1'}, deliveryDate=Thu Oct 10 11:27:20 IDT 2019}

, Car{isReady=3, tyre=null, gear=null, deliveryDate=Fri Oct 11 11:27:20 IDT 2019}

]


查看完整回答
反对 回复 2023-10-13
?
白衣非少年

TA贡献1155条经验 获得超0个赞

老实说,我没有发现你的代码有什么问题。也就是说,如果您的意图是当条目 1 大于条目 2 时返回 -1(与范数相反的顺序)。如果没有更多的代码需要阅读,我认为如果您尝试比较为您的用例构建的值更大或更小,您的代码将会起作用。


但是,我认为您的返回方法效率较低。您不需要返回值。您可以只返回一个实际值。


为了进行比较,您可以先比较 ==,然后再评估其余的。但这可能很难阅读代码,所以我给你两个版本。


删除值版本:


public class CarComparator implements Comparator<Car> {

    @Override

    public int compare(Car entry1, Car entry2) {

        if (entry1.getisReady() > entry2.getisReady()) {

            return -1;

        } else if (entry1.getisReady() < entry2.getisReady()) {

            return 1;

        } else if (entry1.getisReady() == entry2.getisReady()) {

            return 0;

        }

    }

}

删除值和不同风格的比较:


public class CarComparator implements Comparator<Car> {


    @Override

    public int compare(Car entry1, Car entry2) {

        if (entry1.getisReady() == entry2.getisReady()) return 0;            

        return entry1.getisReady() > entry2.getisReady()? -1 : 1;

    }

}

我不确定我是否正确地理解了您的意思,但如果我没有理解,我希望这段代码可以帮助您。我将它们分为 3 个方法,希望您能获得 getTyre() 和 getGear() 方法。您可以根据需要组合它们,对于最后一个方法,其值被分成变量顺序以便于阅读代码。


class CarComparator implements Comparator<Car> {


    public int compare(Car entry1, Car entry2) {

        if (entry1.getisReady() == entry2.getisReady()) return 0;

        return entry1.getisReady() > entry2.getisReady()? -1 : 1;

    }


    public int compareGear(Car entry1, Car entry2){

        if ( (entry1.getGear() != null && entry2.getGear() != null) 

           ||(entry1.getGear() == null && entry2.getGear() == null)

           ){

            return compare(entry1, entry2);

        }  

        return entry1.getGear() != null && entry2.getGear() == null? -1 : 1;


    }


    public int compareTye(Car entry1, Car entry2){

        int order1 = entry1.getGear() != null && entry1.getTyre() != null? 1 : 0;

        int order2 = entry2.getGear() != null && entry2.getTyre() != null? 1 : 0;


        if ( order1 == order2 ) return compare(entry1, entry2);

        return order1 > order2? -1 : 1;

    } 

}


查看完整回答
反对 回复 2023-10-13
  • 4 回答
  • 0 关注
  • 133 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信