我有对象数组person (int age;字符串名称;)。
我如何按名字的字母顺序排序这个数组,然后按年龄?
你会用哪种算法呢?
我有对象数组person (int age;字符串名称;)。
我如何按名字的字母顺序排序这个数组,然后按年龄?
你会用哪种算法呢?
当前回答
或者,您可以利用Collections.sort()(或Arrays.sort())是稳定的(它不会对相等的元素重新排序)这一事实,并首先使用一个Comparator按年龄排序,然后使用另一个Comparator按名称排序。
在这种特定的情况下,这不是一个很好的主意,但如果你必须能够在运行时改变排序顺序,它可能是有用的。
其他回答
使用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时,我会很小心,因为它会为每个被比较的元素创建一个实例,所以如果你在排序,你会看到N x Log N个比较链的创建,或者如果你在迭代和检查相等,则会有N个实例。
如果可能的话,我会使用最新的Java 8 API或Guava的ordered API创建一个静态比较器,这里是Java 8的一个例子:
import java.util.Comparator;
import static java.util.Comparator.naturalOrder;
import static java.util.Comparator.nullsLast;
private static final Comparator<Person> COMPARATOR = Comparator
.comparing(Person::getName, nullsLast(naturalOrder()))
.thenComparingInt(Person::getAge);
@Override
public int compareTo(@NotNull Person other) {
return COMPARATOR.compare(this, other);
}
以下是如何使用番石榴的订购API: https://github.com/google/guava/wiki/OrderingExplained
让你的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()。
我不确定在Person类中写比较器是否丑陋。是这样的:
public class Person implements Comparable <Person> {
private String lastName;
private String firstName;
private int age;
public Person(String firstName, String lastName, int BirthDay) {
this.firstName = firstName;
this.lastName = lastName;
this.age = BirthDay;
}
public int getAge() {
return age;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
@Override
public int compareTo(Person o) {
// default compareTo
}
@Override
public String toString() {
return firstName + " " + lastName + " " + age + "";
}
public static class firstNameComperator implements Comparator<Person> {
@Override
public int compare(Person o1, Person o2) {
return o1.firstName.compareTo(o2.firstName);
}
}
public static class lastNameComperator implements Comparator<Person> {
@Override
public int compare(Person o1, Person o2) {
return o1.lastName.compareTo(o2.lastName);
}
}
public static class ageComperator implements Comparator<Person> {
@Override
public int compare(Person o1, Person o2) {
return o1.age - o2.age;
}
}
}
public class Test {
private static void print() {
ArrayList<Person> list = new ArrayList();
list.add(new Person("Diana", "Agron", 31));
list.add(new Person("Kay", "Panabaker", 27));
list.add(new Person("Lucy", "Hale", 28));
list.add(new Person("Ashley", "Benson", 28));
list.add(new Person("Megan", "Park", 31));
list.add(new Person("Lucas", "Till", 27));
list.add(new Person("Nicholas", "Hoult", 28));
list.add(new Person("Aly", "Michalka", 28));
list.add(new Person("Adam", "Brody", 38));
list.add(new Person("Chris", "Pine", 37));
Collections.sort(list, new Person.lastNameComperator());
Iterator<Person> it = list.iterator();
while(it.hasNext())
System.out.println(it.next().toString());
}
}
您需要实现自己的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));
}
}
}
比较程序首先比较两个名字,如果它们不相等,就返回比较结果,否则就返回比较两人年龄时的比较结果。
这段代码只是一个草稿:因为这个类是不可变的,你可以考虑为它构建一个单例,而不是为每次排序创建一个新实例。