java 按两个字段排序_如何在Java中按两个字段排序?

问题

我有对象数组person (int age; String name;)。

如何按名称和年龄按字母顺序对此数组进行排序?

你会使用哪种算法?

#1 热门回答(161 赞)

你可以使用Collections.sort如下:

private static void order(List persons) {

Collections.sort(persons, new Comparator() {

public int compare(Object o1, Object o2) {

String x1 = ((Person) o1).getName();

String x2 = ((Person) o2).getName();

int sComp = x1.compareTo(x2);

if (sComp != 0) {

return sComp;

}

Integer x1 = ((Person) o1).getAge();

Integer x2 = ((Person) o2).getAge();

return x1.compareTo(x2);

}});

}

List现在按名称排序,然后按年龄排序。

String.compareTo"按字典顺序比较两个字符串" - 来自docs。

Collections.sort是本机Collections库中的静态方法。它进行实际的排序,你只需要提供一个Comparator来定义你的列表中的两个元素应该如何比较:这是通过提供你自己的compare方法的实现来实现的。

#2 热门回答(86 赞)

对于那些能够使用Java 8流API的人来说,这里有一个更为简洁的方法:Lambdas and sorting

我正在寻找相当于C#LINQ:

.ThenBy(...)

我在Comparator上找到了Java 8中的机制:

.thenComparing(...)

所以这里是演示算法的片段。

Comparator comparator = Comparator.comparing(person -> person.name);

comparator = comparator.thenComparing(Comparator.comparing(person -> person.age));

查看上面的链接,了解更简洁的方法以及有关Java类型推断如何使其与LINQ相比更加笨拙的解释。

以下是完整的单元测试供参考:

@Test

public void testChainedSorting()

{

// Create the collection of people:

ArrayList people = new ArrayList<>();

people.add(new Person("Dan", 4));

people.add(new Person("Andi", 2));

people.add(new Person("Bob", 42));

people.add(new Person("Debby", 3));

people.add(new Person("Bob", 72));

people.add(new Person("Barry", 20));

people.add(new Person("Cathy", 40));

people.add(new Person("Bob", 40));

people.add(new Person("Barry", 50));

// Define chained comparators:

// Great article explaining this and how to make it even neater:

// http://blog.jooq.org/2014/01/31/java-8-friday-goodies-lambdas-and-sorting/

Comparator comparator = Comparator.comparing(person -> person.name);

comparator = comparator.thenComparing(Comparator.comparing(person -> person.age));

// Sort the stream:

Stream personStream = people.stream().sorted(comparator);

// Make sure that the output is as expected:

List sortedPeople = personStream.collect(Collectors.toList());

Assert.assertEquals("Andi", sortedPeople.get(0).name); Assert.assertEquals(2, sortedPeople.get(0).age);

Assert.assertEquals("Barry", sortedPeople.get(1).name); Assert.assertEquals(20, sortedPeople.get(1).age);

Assert.assertEquals("Barry", sortedPeople.get(2).name); Assert.assertEquals(50, sortedPeople.get(2).age);

Assert.assertEquals("Bob", sortedPeople.get(3).name); Assert.assertEquals(40, sortedPeople.get(3).age);

Assert.assertEquals("Bob", sortedPeople.get(4).name); Assert.assertEquals(42, sortedPeople.get(4).age);

Assert.assertEquals("Bob", sortedPeople.get(5).name); Assert.assertEquals(72, sortedPeople.get(5).age);

Assert.assertEquals("Cathy", sortedPeople.get(6).name); Assert.assertEquals(40, sortedPeople.get(6).age);

Assert.assertEquals("Dan", sortedPeople.get(7).name); Assert.assertEquals(4, sortedPeople.get(7).age);

Assert.assertEquals("Debby", sortedPeople.get(8).name); Assert.assertEquals(3, sortedPeople.get(8).age);

// Andi : 2

// Barry : 20

// Barry : 50

// Bob : 40

// Bob : 42

// Bob : 72

// Cathy : 40

// Dan : 4

// Debby : 3

}

/**

* A person in our system.

*/

public static class Person

{

/**

* Creates a new person.

* @param name The name of the person.

* @param age The age of the person.

*/

public Person(String name, int age)

{

this.age = age;

this.name = name;

}

/**

* The name of the person.

*/

public String name;

/**

* The age of the person.

*/

public int age;

@Override

public String toString()

{

if (name == null) return super.toString();

else return String.format("%s : %d", this.name, this.age);

}

}

#3 热门回答(55 赞)

使用Java 8 Streams方法......

//Creates and sorts a stream (does not sort the original list)

persons.stream().sorted(Comparator.comparing(Person::getName).thenComparing(Person::getAge));

而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 is similar SYNTAX to the Streams above, but it sorts the original list!!

persons.sort(Comparator.comparing(Person::getName).thenComparing(Person::getAge));


版权声明:本文为weixin_34476847原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。