假设我有一个简单的类:
public class User implements Comparable<User> {
private String name;
private Integer order;
public User(String name, Integer order) {
this.name = name;
this.order = order;
}
//...Getters and Setters ommited
@Override
public int compareTo(User user) {
return this.order.compareTo(user.getOrder());
}
}
只有两个属性,用户名和订单。此属性order
将用于了解用户在列表中的位置。然后,我将创建一个无序LinkedList()
的:
private static List<User> unorderedList() {
final List<User> users = new LinkedList<>();
users.add(new User("Joe", 5));
users.add(new User("John", 2));
users.add(new User("Maria", 8));
users.add(new User("Kevin", 7));
users.add(new User("Sophia", 9));
users.add(new User("James", 1));
users.add(new User("Adrian", 3));
return users;
}
现在,我需要创建一个新User
列表并将其插入到列表中。
User u = new User("David", 2);
但是,在调用该add()
方法之前,我必须做一些事情。
我必须订购此列表(这就是我Comparable
在User类上实现的原因)并且必须将属性更新order
为顺序的。因此,当我在列表中插入新用户时,我需要这样的最终结果:
1 - James // No Change
2 - David // New user inserted
3 - John // Was order 2, become 3
4 - Adrian // Was order 3, become 4
5 - Joe // No Change
6 - Kevin // There was no 6. Kevin was 7 so he become 6
7 - Maria // Was 8
8 - Sophia - // Was 9
编辑1:我尝试了什么
我试图循环列表,并将列表中的用户顺序与新用户顺序进行比较。newUser在列表内的位置具有优先级。
final List<User> unorderedUsers = MainApp.unorderedList();
final AtomicInteger currentOrder = new AtomicInteger(1);
final User newUser = new User("David", 2);
Collections.sort(unorderedUsers);
unorderedUsers.forEach(user -> {
if (user.getOrder().equals(newUser.getOrder())) {
user.setOrder(user.getOrder() + 1);
} else {
user.setOrder(currentOrder.get());
}
currentOrder.incrementAndGet();
});
unorderedUsers.add(newUser);
Collections.sort(unorderedUsers);
System.out.println(String.format("Ordered with new User List -> %s", unorderedUsers));
但是,新的用户订单将重复。我仍在尝试解决如何执行新的顺序订单。我的代码的结果是:
'James', order=1
'David', order=2
'John', order=3
'Adrian', order=3
'Joe', order=4
'Kevin', order=5
'Maria', order=6
'Sophia', order=7
编辑2-可能找到的解决方案我不知道此解决方案是否涵盖所有情况,但我分两个步骤进行。我知道这有点贵,但这是我得到的。
private void insertNewUser(final List <User> usersList, final User newUser) {
final AtomicBoolean canShift = new AtomicBoolean(false);
usersList.forEach(user ->{
if (user.getOrder().equals(newUser.getOrder()) || canShift.get()) {
user.shiftOrder();
canShift.set(true);
}
});
usersList.add(newUser);
Collections.sort(usersList);
}
private void organizeOrder(final List <User> usersList) {
final AtomicInteger currentOrder = new AtomicInteger(1);
usersList.forEach(user -> user.setOrder(currentOrder.getAndIncrement()));
}
然后只需致电:
this.insertNewUser(...)
this.organizeOrder(...)
您不必实现该Comparable
接口。您可以使用进行排序Comparator
:
users.addFirst(newUser);
// We're using addFirst here, because we want to make sure
// that the new user comes BEFORE possible users with the
// same order
AtomicInteger inc = new AtomicInteger();
users.stream()
.sorted(Comparator.comparing(User::getOrder))
.map(user -> {
user.setOrder(inc.incrementAndGet());
return user;
})
.collect(Collectors.toList();
在上面的代码中,发生的事情是这样的:首先,AtomicInteger
创建了一个,这有助于我们为用户提供新的订单号。然后,我们按的序列号对流进行排序User
。然后,我们从中获得一个新的序列号AtomicInteger
,并order
使用该数字设置属性。最后,我们将其收集到一个列表中。
addFirst()
确保将新用户添加到列表的开头。这是因为在最终排序的列表中,我们希望新用户出现在具有相同顺序的任何其他用户之前。由于排序是稳定排序,因此具有相同序号的元素将以与未排序流相同的顺序出现。
作为替代方案addFirst()
,您可以使用代替
newUser.setOrder(newUser.getOrder() - 1);
users.add(newUser);
代替。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句