Ric*_*d H 199
您可以使用Collections.sort如下:
private static void order(List<Person> 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);
}});
}
Run Code Online (Sandbox Code Playgroud)
List<Persons> 现在按名称排序,然后按年龄排序.
String.compareTo"按字典顺序比较两个字符串" - 来自文档.
Collections.sort是本机Collections库中的静态方法.它进行实际的排序,你只需要提供一个Comparator来定义列表中两个元素的比较方式:这是通过提供你自己的compare方法实现来实现的.
Luk*_*ski 129
对于那些能够使用Java 8流API的人来说,这里有一个更为简洁的方法: Lambdas和排序
我正在寻找相当于C#LINQ:
.ThenBy(...)
Run Code Online (Sandbox Code Playgroud)
我在Comparator上找到了Java 8中的机制:
.thenComparing(...)
Run Code Online (Sandbox Code Playgroud)
所以这里是演示算法的片段.
Comparator<Person> comparator = Comparator.comparing(person -> person.name);
comparator = comparator.thenComparing(Comparator.comparing(person -> person.age));
Run Code Online (Sandbox Code Playgroud)
查看上面的链接,了解更简洁的方法以及有关Java类型推断如何使其与LINQ相比更加笨拙的解释.
以下是完整的单元测试供参考:
@Test
public void testChainedSorting()
{
// Create the collection of people:
ArrayList<Person> 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<Person> comparator = Comparator.comparing(person -> person.name);
comparator = comparator.thenComparing(Comparator.comparing(person -> person.age));
// Sort the stream:
Stream<Person> personStream = people.stream().sorted(comparator);
// Make sure that the output is as expected:
List<Person> 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);
}
}
Run Code Online (Sandbox Code Playgroud)
Bra*_*y D 95
使用Java 8 Streams方法......
//Creates and sorts a stream (does not sort the original list)
persons.stream().sorted(Comparator.comparing(Person::getName).thenComparing(Person::getAge));
Run Code Online (Sandbox Code Playgroud)
而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());
}
});
Run Code Online (Sandbox Code Playgroud)
最后...
//This is similar SYNTAX to the Streams above, but it sorts the original list!!
persons.sort(Comparator.comparing(Person::getName).thenComparing(Person::getAge));
Run Code Online (Sandbox Code Playgroud)
Ral*_*lph 17
您需要实现自己的Comparator,然后使用它:例如
Arrays.sort(persons, new PersonComparator());
Run Code Online (Sandbox Code Playgroud)
您的比较器可能看起来像这样:
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));
}
}
}
Run Code Online (Sandbox Code Playgroud)
比较器首先比较名称,如果它们不相等则返回比较它们的结果,否则它在比较两个人的年龄时返回比较结果.
这段代码只是草稿:因为类是不可变的,你可以考虑构建它的单例,而不是为每个排序创建一个新实例.
Mic*_*rry 13
让你的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;
}
}
Run Code Online (Sandbox Code Playgroud)
这将首先按名称排序(不区分大小写)然后按年龄排序.然后,您可以运行Arrays.sort()或Collections.sort()在Person对象的集合或数组.
小智 10
您可以使用Java 8 Lambda方法来实现。像这样:
persons.sort(Comparator.comparing(Person::getName).thenComparing(Person::getAge));
Run Code Online (Sandbox Code Playgroud)
GuavaComparisonChain提供了一种干净的方法。请参阅此链接。
用于执行链接比较语句的实用程序。例如:
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();
}
Run Code Online (Sandbox Code Playgroud)
你可以这样做:
List<User> users = Lists.newArrayList(
new User("Pedro", 12),
new User("Maria", 10),
new User("Rafael",12)
);
users.sort(
Comparator.comparing(User::getName).thenComparing(User::getAge)
);
Run Code Online (Sandbox Code Playgroud)
使用 Guava 时我会小心,ComparisonChain因为它会为每个比较的元素创建一个实例,因此您将查看N x Log N比较链的创建,以便在排序时进行比较,或者N在迭代和检查是否相等时查看实例。
Comparator如果可能的话,我会使用最新的 Java 8 API 或允许您执行此操作的 Guava 的API创建静态Ordering,这是 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);
}
Run Code Online (Sandbox Code Playgroud)
以下是如何使用 Guava 的OrderingAPI:https://github.com/google/guava/wiki/OrderingExplained
| 归档时间: |
|
| 查看次数: |
156662 次 |
| 最近记录: |