背景:ArrayList是我们最常用的集合框架之一。排序在使用TreeSet是非常方便,但是TreeSet集合有默认的排序算法在里面,所有TreeSet里数据,只要加进去就会自动使用默认的排序方法排序,如果希望默认情况下,取出数据的顺序按照存入数据的顺序,需要排序的时候在去自定义排序怎么办呢?还得用回ArrayList集合。
准备:创建一个Person类(Person.java),里面包含两类属性:姓名和年龄。
package Person_bean;
public class Person implements Comparable<Person> {
private String name;
private int age;
public Person() { //空参构造
}
public Person(String name, int age) { //有参构造
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() { //重写toString方法
return name + "," + age;
}
创建住方法类:Demo_ArrayList.java
package DemoDate;
import Person_bean.Person;
import java.util.ArrayList;
public class Demo_ArrayList {
public static void main(String[] args) {
ArrayList<Person> al = new ArrayList<>();
al.add(new Person("张三", 23));
al.add(new Person("李四", 29));
al.add(new Person("王五", 25));
al.add(new Person("赵六", 23));
al.add(new Person("周七", 29));
al.add(new Person("周七", 21));
创建排序方法:
可以重写Peron类中的CompareTo方法,也可以在Person类中创建自己的方法,我的习惯是,重写CompareTo方法留给TreeSet,其他集合使用的方法自己创建,因为ComparaTo方法是被TreeSet默认加载的。
package Person_bean;
import java.text.Collator;
import java.util.Locale;
import java.util.Objects;
public class Person implements Comparable<Person> {
private String name;
private int age;
.
.
.
@Override
public String toString() {
return name + "," + age;
}
//添加按照姓名排序方法
public int compByName(Person p) {
Collator c = Collator.getInstance(Locale.CHINA);
int numForName = c.compare(this.getName(), p.getName());
return numForName == 0 ? this.getAge() - p.getAge() : numForName;
}
//添加按照年龄排序方法
public int compByAge(Person p) {
Collator c = Collator.getInstance(Locale.CHINA);
int numForAge = this.getAge() - p.getAge();
return numForAge == 0 ? c.compare(this.getName(), p.getName()) : numForAge;
}
使用排序方法
package DemoDate;
import Person_bean.Person;
import java.util.ArrayList;
public class Demo_ArrayList {
public static void main(String[] args) {
ArrayList<Person> al = new ArrayList<>();
al.add(new Person("张三", 23));
al.add(new Person("李四", 29));
al.add(new Person("王五", 25));
al.add(new Person("赵六", 23));
al.add(new Person("周七", 29));
al.add(new Person("周七", 21));
//使用按照姓名排序方法
al.sort(Person::compByName);
System.out.println(al);
//使用按照年龄排序方法
al.sort(Person::compByAge);
System.out.println(al);
注:在使用默认的compareTo方法对汉语姓名进行排序的时候,是按照Unicode编码排序的,导致“张三”比“李四"还小,以致“张三”排到了"李四"的前面,如果希望按照汉语的拼音顺序排类,就需要用到Collator这个抽象类,指定本地编码才能拿到想要的排序效果。
运行结果:
[李四,29, 王五,25, 张三,23, 赵六,23, 周七,21, 周七,29]
[周七,21, 张三,23, 赵六,23, 王五,25, 李四,29, 周七,29]
总结:
目标:对汉语的姓名,按照拼音的顺序排序
必备前提:需要使用本地化,会使用到Collator类,所以要重写compare方法。
解决方法:1,自定义方法,使用compare方法比较(同上述实例)。2,创建一个新的比较器类,实现comparator,然后重写compare方法。如:
class sortByName implements Comparator<Person> {
@Override
public int compare(Person o1, Person o2) {
Collator c = Collator.getInstance(Locale.CHINA);
int num = c.compare(o1.getName(),o2.getName());
return num == 0 ? o1.getAge() - o2.getAge() : num;
}
然后使用新的比较器去排序
al.sort(new sortByName);
网友评论