我有对象数组person (int age;字符串名称;)。

我如何按名字的字母顺序排序这个数组,然后按年龄?

你会用哪种算法呢?


当前回答

Guava的ComparisonChain提供了一种干净的方法。参考这个链接。

用于执行链式比较语句的实用程序。例如:

   public int compareTo(Foo that) {
     return ComparisonChain.start()
         .compare(this.aString, that.aString)
         .compare(this.anInt, that.anInt)
         .compare(this.anEnum, that.anEnum, Ordering.natural().nullsLast())
         .result();
   }

其他回答

根据需要创建尽可能多的比较器。之后,为每个订单类别调用“then comparison”方法。这是Streams的一种做法。看到的:

//Sort by first and last name
System.out.println("\n2.Sort list of person objects by firstName then "
                                        + "by lastName then by age");
Comparator<Person> sortByFirstName 
                            = (p, o) -> p.firstName.compareToIgnoreCase(o.firstName);
Comparator<Person> sortByLastName 
                            = (p, o) -> p.lastName.compareToIgnoreCase(o.lastName);
Comparator<Person> sortByAge 
                            = (p, o) -> Integer.compare(p.age,o.age);

//Sort by first Name then Sort by last name then sort by age
personList.stream().sorted(
    sortByFirstName
        .thenComparing(sortByLastName)
        .thenComparing(sortByAge)
     ).forEach(person->
        System.out.println(person));        

在多个字段上对用户定义的对象进行排序- Comparator (lambda stream)

使用Comparator,然后将对象放入Collection,然后Collections.sort();

class Person {

    String fname;
    String lname;
    int age;

    public Person() {
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getFname() {
        return fname;
    }

    public void setFname(String fname) {
        this.fname = fname;
    }

    public String getLname() {
        return lname;
    }

    public void setLname(String lname) {
        this.lname = lname;
    }

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

    @Override
    public String toString() {
        return fname + "," + lname + "," + age;
    }
}

public class Main{

    public static void main(String[] args) {
        List<Person> persons = new java.util.ArrayList<Person>();
        persons.add(new Person("abc3", "def3", 10));
        persons.add(new Person("abc2", "def2", 32));
        persons.add(new Person("abc1", "def1", 65));
        persons.add(new Person("abc4", "def4", 10));
        System.out.println(persons);
        Collections.sort(persons, new Comparator<Person>() {

            @Override
            public int compare(Person t, Person t1) {
                return t.getAge() - t1.getAge();
            }
        });
        System.out.println(persons);

    }
}

Guava的ComparisonChain提供了一种干净的方法。参考这个链接。

用于执行链式比较语句的实用程序。例如:

   public int compareTo(Foo that) {
     return ComparisonChain.start()
         .compare(this.aString, that.aString)
         .compare(this.anInt, that.anInt)
         .compare(this.anEnum, that.anEnum, Ordering.natural().nullsLast())
         .result();
   }

使用Java 8 Streams方法,在getter上引用方法…

// Create a stream...
var sortedList = persons.stream()
    // sort it (does not sort the original list)...
    .sorted(Comparator.comparing(Person::getName)
                      .thenComparing(Person::getAge));
    // and collect to a new list
    .collect(Collectors.toList());

集合到数组ist也可以:

persons.stream()
    .sorted(Comparator.comparing(Person::getName)
                      .thenComparing(Person::getAge));
    .toArray(String[]::new);

Java 8 Lambda方法……

//Sorts the original list Lambda style
persons.sort((p1, p2) -> {
        if (p1.getName().compareTo(p2.getName()) == 0) {
            return p1.getAge().compareTo(p2.getAge());
        } else {
            return p1.getName().compareTo(p2.getName());
        } 
    });

最后……

// This syntax is similar to the Streams example above, but sorts the original list!!!
persons.sort(Comparator.comparing(Person::getName).thenComparing(Person::getAge));

您需要实现自己的Comparator,然后使用它:例如

Arrays.sort(persons, new PersonComparator());

你的比较器可以看起来像这样:

public class PersonComparator implements Comparator<? extends Person> {

  public int compare(Person p1, Person p2) {
     int nameCompare = p1.name.compareToIgnoreCase(p2.name);
     if (nameCompare != 0) {
        return nameCompare;
     } else {
       return Integer.valueOf(p1.age).compareTo(Integer.valueOf(p2.age));
     }
  }
}

比较程序首先比较两个名字,如果它们不相等,就返回比较结果,否则就返回比较两人年龄时的比较结果。

这段代码只是一个草稿:因为这个类是不可变的,你可以考虑为它构建一个单例,而不是为每次排序创建一个新实例。