Ken*_*thC 11 java sorting comparator java-8
我想根据用户列表的状态对用户列表进行排序,但订单必须基于我设置的顺序.
我想设置列表的顺序,
订单应为1,0,5.我们还应该记住订购用户名.
List<User> users = new ArrayList();
users.add(new User("A", 1));
users.add(new User("B", 5));
users.add(new User("C", 0));
users.add(new User("D", 1));
users.add(new User("E", 5));
users.add(new User("F", 0));
Run Code Online (Sandbox Code Playgroud)
这是用户类
public class User {
private String username;
private Integer status;
}
Run Code Online (Sandbox Code Playgroud)
它看起来应该是这样的
[
{
"username": "A",
"status": 1
},
{
"username": "D",
"status": 1
},
{
"username": "C",
"status": 0
},
{
"username": "F",
"status": 0
},
{
"username": "B",
"status": 5
},
{
"username": "E",
"status": 5
}
]
Run Code Online (Sandbox Code Playgroud)
我不确定是否可以使用Comparator.comparing,因为这个既不是升序也不是降序.
一种方法可以是保存包含所需顺序的列表,并根据其索引对用户进行排序:
final List<Integer> order = Arrays.asList(1, 0, 5);
users.sort(
Comparator.comparing((User u) -> order.indexOf(u.getStatus()))
.thenComparing(User::getUsername));
Run Code Online (Sandbox Code Playgroud)
请注意,虽然这种方法对于少数状态(如您目前所拥有)应该是合理的,但如果存在大量状态并且您每次都需要执行O(n)搜索,则可能会降低排序速度.一个表现更好的方法(尽管可能不那么光滑),就是使用地图:
final Map<Integer, Integer> order = new HashMap<>();
order.put(1, 0);
order.put(0, 1);
order.put(5 ,2);
users.sort(Comparator.comparing((User u) -> order.get(u.getStatus()))
.thenComparing(User::getUsername));
Run Code Online (Sandbox Code Playgroud)
如果您不介意在项目中使用Guava,可以使用Ordering.explicit:
users.sort(Ordering.explicit(1, 0, 5).onResultOf(User::getStatus));
Run Code Online (Sandbox Code Playgroud)
如果您还想按名称排序,请添加thenComparing:
users.sort(Ordering
.explicit(1, 0, 5)
.onResultOf(User::getStatus)
.thenComparing(User::getUsername));
Run Code Online (Sandbox Code Playgroud)