Java 提供的 List 接口继承了 Collection 接口,因此包含 Collection 中的所有方法。List 是有序集合,允许有相同的元素。ArrayList 是List 接口的一个实现类,它实现了可变大小的数值,允许所有元素,包括 null,并可以根据索引位置对集合进行快速的随机访问。
下面将通过实例来实现使用 Comparator 接口、Collections.sor() 方法、stream().sorted() 方法实现集合的排序。
Comparator 接口、Collections.sor() 方法位于 java.util 包中。
stream().sorted() 方法位于 java.util.stream.Collectors 类下。
博文系列:
《Java实现List集合的排序:Comparator接口、Collections.sort()方法、stream().sorted()方法的使用》
(1)创建用户信息实体类
/**
* 用户信息实体类
* @author pan_junbiao
**/
public class UserInfo
{
private int userId; //用户编号
private String userName; //用户名称
private int age; //年龄
private String blogInfo; //博客信息
//构造函数
public UserInfo(int userId, String userName, int age, String blogInfo)
{
this.userId = userId;
this.userName = userName;
this.age = age;
this.blogInfo = blogInfo;
}
public int getUserId()
{
return userId;
}
public void setUserId(int userId)
{
this.userId = userId;
}
public String getUserName()
{
return userName;
}
public void setUserName(String userName)
{
this.userName = userName;
}
public int getAge()
{
return age;
}
public void setAge(int age)
{
this.age = age;
}
public String getBlogInfo()
{
return blogInfo;
}
public void setBlogInfo(String blogInfo)
{
this.blogInfo = blogInfo;
}
@Override
public String toString()
{
return "用户编号:" + this.userId + " 用户名称:" + this.userName
+ " 年龄:" + this.age + " 博客信息:" + this.blogInfo;
}
}
(2)编写获取用户信息列表方法
/**
* 获取用户信息列表
* @author pan_junbiao
*/
private List<UserInfo> getUserList()
{
List<UserInfo> userList = new ArrayList<>();
//创建用户信息
UserInfo user1 = new UserInfo(1,"pan_junbiao的博客_01", 18, "您好,欢迎访问 pan_junbiao的博客");
UserInfo user2 = new UserInfo(2,"pan_junbiao的博客_02", 41, "https://blog.csdn.net/pan_junbiao");
UserInfo user3 = new UserInfo(3,"pan_junbiao的博客_03", 35, "您好,欢迎访问 pan_junbiao的博客");
UserInfo user4 = new UserInfo(4,"pan_junbiao的博客_04", 32, "https://blog.csdn.net/pan_junbiao");
//将用户信息加入Map(故意打乱顺序)
userList.add(user4);
userList.add(user2);
userList.add(user3);
userList.add(user1);
return userList;
}
1、Comparator接口
Comparator 接口是一个比较器(比较接口),在 Java 中,可以通过使用 Comparator 接口实现集合或数组的排序。实现 Comparator 接口时,需要重写 int compare(T o1, T o2) 方法,但可以不重新 boolean equals(Object obj) 方法。
(1) int compare(T o1, T o2) 方法:是比较 o1 和 o2 的大小,其中 o1 指的就是第一个要比较的对象, o2 指的是第二个要比的对象。 比较之后会根据大小返回值:
若返回值为负数, 表示 o1 小于 o2小;
若返回值为 0,表示 o1 等于 o2;
若返回值为正数,表示 o1 大于 o2 ;
(2)boolean equals(Object obj) 方法:该方法可以不必重写。然而,在某些情况下,重写此方法可以允许程序确定两个不同的 Comparator 是否强行实施了相同的排序,从而提高性能。
2、Collections.sort()方法
Collections 类提供了两种 sort() 排序方法,分别如下:
(1)sort() 排序方法一:
public static <T extends Comparable<? super T>> void sort(List<T> list)
{
list.sort(null);
}
该方法中的泛型 <T> 都是 Comparable 接口的子类,即只有是 Comparable 接口子类类型的对象,才能进行比较排序。如果其他类型的数据要进行比较排序,必须继承 Comparable 接口并重写 int compare(T o1, T o2) 方法和 boolean equals(Object obj) 方法。
(2)sort() 排序方法二:
public static <T> void sort(List<T> list, Comparator<? super T> c) {
list.sort(c);
}
该方法中指定比较方式 Comparator<? super T> c,即 c 必须实现 Comparator<? super T> 接口,重写 compareTo() 方法指定比较项目。比较项目在类外指定,比较灵活。
【示例】使用 Comparator 比较接口和 Collections.sort() 排序方法实现用户信息的排序。
/**
* 使用 Comparator 比较接口和 Collections.sort() 排序方法实现用户信息的排序
* @author pan_junbiao
*/
@Test
public void testUserSort()
{
//获取用户信息列表
List<UserInfo> userList = getUserList();
//排序1:按照用户年龄升序
Collections.sort(userList, new Comparator<UserInfo>()
{
@Override
public int compare(UserInfo user1, UserInfo user2)
{
Integer age1 = user1.getAge();
Integer age2 = user2.getAge();
return age1.compareTo(age2);
}
});
System.out.println("按照用户年龄升序:");
for(UserInfo user : userList)
{
System.out.println(user);
}
//排序2:按照用户名称倒序
Collections.sort(userList, new Comparator<UserInfo>()
{
@Override
public int compare(UserInfo user1, UserInfo user2)
{
String userName1 = user1.getUserName();
String userName2 = user2.getUserName();
return userName2.compareTo(userName1);
}
});
System.out.println("\n按照用户名称倒序:");
for(UserInfo user : userList)
{
System.out.println(user);
}
}
执行结果:
3、stream().sorted()方法
如果流中的元素的类实现了 Comparable 接口,即有自己的排序规则,那么可以直接调用 sorted() 方法对元素进行排序,如 Stream。反之, 需要调用 sorted((T, T) -> int) 实现 Comparator 接口。
【示例】使用 stream().sorted() 方法实现用户列表根据的排序升序。
/**
* 使用stream().sorted()方法实现用户列表根据的排序升序
* @author pan_junbiao
*/
@Test
public void testStreamSorted()
{
//获取用户信息列表
List<UserInfo> userList = getUserList();
//根据年龄排序(升序)
userList = userList.stream().sorted((u1, u2) -> u1.getAge() - u2.getAge()).collect(Collectors.toList());
//推荐:userList = userList.stream().sorted(Comparator.comparingInt(User::getAge)).collect(Collectors.toList());
//降序:userList = userList.stream().sorted(Comparator.comparingInt(User::getAge).reversed()).collect(Collectors.toList());
//遍历用户列表
System.out.println("按照用户年龄升序:");
userList.forEach(System.out::println);
}
推荐使用如下写法:
//升序
userList = userList.stream().sorted(Comparator.comparingInt(User::getAge)).collect(Collectors.toList());
//降序
userList = userList.stream().sorted(Comparator.comparingInt(User::getAge).reversed()).collect(Collectors.toList());
执行结果: