Lan*_*ali 3 java collections list-comprehension
我有一个本地商店中的用户列表,我需要每隔一段时间从远程用户列表更新.基本上:
例如.远程列表:用户(1,真),用户(2,真),用户(4,真),用户(5,真)
本地列表:用户(1,真),用户(2,假),用户(3,真),用户(6,真)
新的本地列表:用户(1,真),用户(2,真),用户(3,假),用户(4,真),用户(5,真),用户(6,假),
只是一个同步本地列表的简单案例.有没有更好的方法在纯Java中执行此操作而不是以下?我觉得自己很难看自己的代码.
public class User {
Integer id;
String email;
boolean active;
//Getters and Setters.......
public User(Integer id, String email, boolean active) {
this.id = id;
this.email = email;
this.active = active;
}
@Override
public boolean equals(Object other) {
boolean result = false;
if (other instanceof User) {
User that = (User) other;
result = (this.getId() == that.getId());
}
return result;
}
}
public static void main(String[] args) {
//From 3rd party
List<User> remoteUsers = getRemoteUsers();
//From Local store
List<User> localUsers =getLocalUsers();
for (User remoteUser : remoteUsers) {
boolean found = false;
for (User localUser : localUsers) {
if (remoteUser.equals(localUser)) {
found = true;
localUser.setActive(remoteUser.isActive());
localUser.setEmail(remoteUser.getEmail());
//update
}
break;
}
if (!found) {
User user = new User(remoteUser.getId(), remoteUser.getEmail(), remoteUser.isActive());
//Save
}
}
for(User localUser : localUsers ) {
boolean found = false;
for(User remoteUser : remoteUsers) {
if(localUser.equals(remoteUser)) {
found = true;
localUser.setActive(remoteUser.isActive());
localUser.setEmail(remoteUser.getEmail());
//Update
}
break;
}
if(!found) {
localUser.setActive(false);
// Deactivate
}
}
}
Run Code Online (Sandbox Code Playgroud)
最好的方法是切换到不同的数据结构.A Map<Integer, User>将是最好的,因为可能用户具有唯一标识ID.您的Map实现选择可以是HashMap(预期O(1)用于基本操作)或a TreeMap(O(log N)).
重要提示:你@Override equals(Object)没有@Override hashCode()!!! 这很危险!你应该总是养成不要两者兼顾的习惯!(请参阅:
在Java中覆盖equals和hashCode
)
所以,让我们说你有Map<Integer, User> remoteUsers和Map<Integer, User> localUsers.
1.)如果远程用户已在本地存在,请更新其字段.
4.)如果本地用户也出现在远程列表中,请更新其字段.(与1相同)
2.)如果本地尚不存在远程用户,请添加用户.
如果发现User来自remoteUsers于localUsers在回答O(1)或O(log N)用一个简单的containsKey和get.
for (int id : remoteUsers.keys()) {
User local;
if (localUsers.containsKey(id)) {
local = localUsers.get(id);
else {
localUsers.put(id, local = new User(id));
}
local.updateFrom(remoteUsers.get(id));
}
Run Code Online (Sandbox Code Playgroud)
3.)如果本地用户未出现在远程列表中,则取消激活或删除.
以下解决方案显示了这些更高级的数据结构的强大功能:
Set<Integer> toDeactivate = new TreeSet<Integer>();
toDeactivate.addAll(localUsers.keySet());
toDeactivate.removeAll(remoteUsers.keySet());
for (int id : toDeactivate) {
User local = localUsers.get(id);
local.deactivate();
localUsers.remove(id);
}
Run Code Online (Sandbox Code Playgroud)
此外,如果您坚持使用List<User>,您仍然可以Map<Integer, User>用作此处理的中间数据结构(基本上转换List<User>为Map<Integer, User>然后返回List<User>).它会更快,因为它O(N log N)或者O(N)与O(N^2)你现在相比更快.
如果你坚持只使用列表,那么你可能想看看它是一个Collections.sort-ed列表,所以你可以做一个Collections.binarySearch.您需要提供Comparator<User>或User implements Comparable<User>自然订购id.这也是O(N log N).