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

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

你会用哪种算法呢?


当前回答

使用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));

其他回答

根据需要创建尽可能多的比较器。之后,为每个订单类别调用“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)

让你的person类实现Comparable< person >,然后实现compareTo方法,例如:

public int compareTo(Person o) {
    int result = name.compareToIgnoreCase(o.name);
    if(result==0) {
        return Integer.valueOf(age).compareTo(o.age);
    }
    else {
        return result;
    }
}

它将首先按名称(大小写不敏感)排序,然后按年龄排序。然后可以在Person对象的集合或数组上运行Arrays.sort()或Collections.sort()。

您需要实现自己的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));
     }
  }
}

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

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

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



import java.util.Comparator;

public class PersonComparator implements Comparator<? extends Person> {

    @Override
    public int compare(Person o1, Person o2) {
        if(null == o1 || null == o2  || null == o1.getName() || null== o2.getName() ){
            throw new NullPointerException();
        }else{
            int nameComparisonResult = o1.getName().compareTo(o2.getName());
            if(0 == nameComparisonResult){
                return o1.getAge()-o2.getAge();
            }else{
                return nameComparisonResult;
            }
        }
    }
}


class Person{
    int age; String name;

    public int getAge() {
        return age;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

升级版:

public class PersonComparator implements Comparator<? extends Person> {

   @Override
   public int compare(Person o1, Person o2) {

      int nameComparisonResult = o1.getName().compareToIgnoreCase(o2.getName());
      return 0 == nameComparisonResult?o1.getAge()-o2.getAge():nameComparisonResult;

   }
 }

或者,您可以利用Collections.sort()(或Arrays.sort())是稳定的(它不会对相等的元素重新排序)这一事实,并首先使用一个Comparator按年龄排序,然后使用另一个Comparator按名称排序。

在这种特定的情况下,这不是一个很好的主意,但如果你必须能够在运行时改变排序顺序,它可能是有用的。