简体   繁体   English

使用比较器或比较器降序排序对象

[英]Descending sort of object using comparable or comparator

So I have a Hill object that contains information about hills that is obtained from a CSV file. 因此,我有一个Hill对象,其中包含有关从CSV文件获取的hills的信息。 The file looks like this: 该文件如下所示:

import java.io.IOException;
import java.net.URL;
import java.util.*;



public class Hill implements Comparable<Hill>{
    public static final String CSV_FILE_URL = "HIDDEN";
    public static final String DELIMITER = ",";
    public int number;
    public String name,county;
    public double height,lat,lon;


    public Hill(int number,String name,String county,double height,double lat,double lon){
        this.number = number;
        this.name = name;
        this.county = county;
        this.height = height;
        this.lat = lat;
        this.lon = lon;

    }

    public String toString(){
        return(number + ", " + name + ", " + county + ", " + height + ", " + lat + ", " + lon);
    }

    public static List<Hill> readHills() throws IOException{
        String[] fields = new String[0];
        URL url = new URL(CSV_FILE_URL);
        Scanner input = new Scanner(url.openConnection().getInputStream());
        List<Hill> hillList = new ArrayList<>();
        input.nextLine();
        while(input.hasNextLine()){
            fields = input.nextLine().split(DELIMITER);
            Hill hill = new Hill(Integer.parseInt(fields[0]),fields[1],fields[2],Double.parseDouble(fields[3]),Double.parseDouble(fields[4]),Double.parseDouble(fields[5]));
            hillList.add(hill);

        }

        return hillList;
    }


    @Override
    public int compareTo(Hill o) {
        return this.name.compareTo(o.name);
    }


}

Inside my exercise class I am currently able to sort the hills alphabetically using the Comparable interface. 在我的运动课中,我目前能够使用Comparable接口按字母顺序对丘陵进行排序。 I then get it to print the first 20 hills. 然后我得到它来打印前20个山丘。

Now I wish to sort the hills list by height but descending so that I can print out the 20 tallest hills. 现在,我想按高度排序,但降序排序,以便打印出20个最高的山丘。

import java.io.IOException;
import java.util.*;

public class Exercise5 {

    public static void exercise5d() throws IOException {
        System.out.println("### Exercise 5D ###");
        List listOfHills = Hill.readHills();
        Collections.sort(listOfHills);
        for(int x=0;x<20;x++){
            System.out.println(listOfHills.get(x));
        }
        System.out.println("");

        //Attempt at reversing
        Comparator<Hill> HillComparator = Collections.reverseOrder();
        Collections.sort(listOfHills,HillComparator);
        for(int x=0;x<20;x++){
            System.out.println(listOfHills.get(x));
        }



    }

    public static void main(String[] args) throws IOException {
        exercise5d();
    }
}

Here is an example that shows how you can use Comparable or a Comparator : 这是显示如何使用ComparableComparator的示例:

/*
**  Use the Collections API to sort a List for you.
**
**  When your class has a "natural" sort order you can implement
**  the Comparable interface.
**
**  You can use an alternate sort order when you implement
**  a Comparator for your class.
*/
import java.util.*;

public class Person implements Comparable<Person>
{
    String name;
    int age;

    public Person(String name, int age)
    {
        this.name = name;
        this.age = age;
    }

    public String getName()
    {
        return name;
    }

    public int getAge()
    {
        return age;
    }

    public String toString()
    {
        return name + " : " + age;
    }

    /*
    **  Implement the natural order for this class
    */
    public int compareTo(Person p)
    {
        return getName().compareTo(p.getName());
    }

    static class AgeComparator implements Comparator<Person>
    {
        public int compare(Person p1, Person p2)
        {
            return p1.getAge() - p2.getAge();
        }
    }

    public static void main(String[] args)
    {
        List<Person> people = new ArrayList<Person>();
        people.add( new Person("Homer", 38) );
        people.add( new Person("Marge", 35) );
        people.add( new Person("Bart", 15) );
        people.add( new Person("Lisa", 13) );

        // Sort by natural order

        Collections.sort(people);
        System.out.println("Sort by Natural order");
        System.out.println("\t" + people);

        // Sort by reverse natural order

        Collections.sort(people, Collections.reverseOrder());
        System.out.println("Sort by reverse natural order");
        System.out.println("\t" + people);

        //  Use a Comparator to sort by age

        Collections.sort(people, new Person.AgeComparator());
        System.out.println("Sort using Age Comparator");
        System.out.println("\t" + people);

        //  Use a Comparator to sort by descending age

        Collections.sort(people, Collections.reverseOrder(new Person.AgeComparator()));
        System.out.println("Sort using Reverse Age Comparator");
        System.out.println("\t" + people);

        //  Use a Comparator with lambda expression to sort by age

//      Collections.sort(people, (o1, o2) -> o1.getAge() - o2.getAge());
//      Collections.sort(people, Comparator.comparingInt(p -> p.getAge()));
        Collections.sort(people, Comparator.comparingInt(Person::getAge));
        System.out.println("Sort using Lambda Age Comparator");
        System.out.println("\t" + people);
    }
}

So you just need to implement the Comparator for your Hill class on whatever property(s) you want. 因此,您只需要在所需的任何属性上为Hill类实现Comparator

Your basic implementation of Comparable compares the names of the hills, it has nothing to do with the height 您的Comparable基本实现方式Comparable了山丘的名称,与高度无关

How can I adjust Comparable so that it allows me to sort by name and then by height after? 如何调整“可比性”,以便我可以按名称排序,然后按身高排序?

Create a new Comparator which implements the logic you need to compare the heights and use that with Collections.sort 创建一个新的Comparator,它实现比较高度并将其与Collections.sort结合使用所需的逻辑

Collections.sort(listOfHills, new Comparator<Hill>() {
    @Override
    public int compare(Hill o1, Hill o2) {
        return o2.height > o1.height ? (o2.height == o1.height ? 0 : 1) : -1;
    }
});

This is one of the reasons I don't normally implement Comparator on objects, unless their is a good business rule associated with how the object should be compared, it's easily to provide a number of custom Comparator s (or allow other developers to devise their own) which implement "common" algorithms - but that's me 这是我通常不对对象实施Comparator的原因之一,除非它们是与如何比较对象相关的良好业务规则,否则很容易提供许多自定义Comparator (或允许其他开发人员设计他们的对象)。自己)来实现“通用”算法-就是我

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

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