为了账号安全,请及时绑定邮箱和手机立即绑定

Java 8 - 基于特定顺序的自定义排序

Java 8 - 基于特定顺序的自定义排序

潇潇雨雨 2022-01-12 17:18:44
我想根据用户的状态对用户列表进行排序,但顺序必须基于我设置的顺序。我想设置列表的顺序,顺序应该是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));这是用户类public class User {         private String username;         private Integer status;     }它应该看起来像这样[    {      "username": "A",      "status": 1    },    {       "username": "D",       "status": 1    },    {       "username": "C",       "status": 0    },    {       "username": "F",       "status": 0    },    {       "username": "B",       "status": 5    },    {       "username": "E",       "status": 5    }]我不确定是否可以使用Comparator.comparing,因为这个既不是升序也不是降序。
查看完整描述

3 回答

?
月关宝盒

TA贡献1772条经验 获得超5个赞

一种方法可能是按照您想要的顺序保存一个列表,并根据其索引对用户进行排序:


final List<Integer> order = Arrays.asList(1, 0, 5);

users.sort(

    Comparator.comparing((User u) -> order.indexOf(u.getStatus()))

              .thenComparing(User::getUsername));

请注意,虽然这种方法对于少数状态(就像您目前拥有的那样)应该是合理的,但如果有大量状态并且您每次都需要执行 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));


查看完整回答
反对 回复 2022-01-12
?
米琪卡哇伊

TA贡献1998条经验 获得超6个赞

如果你不介意在你的项目中使用 Guava,你可以使用Ordering.explicit:


users.sort(Ordering.explicit(1, 0, 5).onResultOf(User::getStatus));

如果您还想按名称排序,请添加thenComparing:


users.sort(Ordering

        .explicit(1, 0, 5)

        .onResultOf(User::getStatus)

        .thenComparing(User::getUsername));


查看完整回答
反对 回复 2022-01-12
?
HUWWW

TA贡献1874条经验 获得超12个赞

假设1,05will 是 的唯一值status,AJNeufeld 在他们的评论中提出了一个极好的观点;他们说您可以使用方程式将每个值映射到升序。在这种情况下,等式将是 的值在(x - 1)^2哪里:xstatus

users.sort(Comparator.comparingDouble(user -> Math.pow(user.getStatus() - 1, 2)));

如果您要user在调用上述代码段后打印 的内容,您会得到:

[用户[用户名=A,状态=1],用户[用户名=D,状态=1],用户[用户名=C,状态=0],用户[用户名=F,状态=0],用户[用户名=B , 状态=5], 用户 [用户名=E, 状态=5]]


查看完整回答
反对 回复 2022-01-12
  • 3 回答
  • 0 关注
  • 586 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信