在列表中查找重复的组合

时间:2012-02-17 04:24:03

标签: algorithm data-structures

用户输入用户名,密码和系统生成唯一字段。 每个用户名密码组合以及自动生成的唯一字段作为对象存储在List中。 我想知道列表中是否重复了用户名 - 密码组合(不考虑唯一密钥)。

我想避免使用for循环来解决这个问题。使用hashmap查明是否存在重复组合 -

//hm is the hashmap...
//up is the list....
for(int i=0; i<up.length(); i++){
  if(hm.contains(up[i])){
    System.out.println("Repeated combination");
    break;
    }
   else{
       hm.put(up[i],i);
    }
 }

然而,该对象具有唯一的自动生成字段,并且上述逻辑不起作用。任何以最快的方式实现这一目标的建议。

1 个答案:

答案 0 :(得分:1)

我假设up [i]是一些类(User),其用户名,密码和unique_id为三个字段。

如果这是真的,你可以创建这个类的包装器(UserWrapper)并覆盖equals / hashCode方法,只依赖于User类的用户名/密码属性。

这应该非常快速地编码/测试

编辑:示例类如下。你可以使用LinkedHashMap(这样你就可以拥有地图功能,并且用户的订购方式与放入用户的方式相同)

class User {
    private final String id = UUID.randomUUID().toString();
    private final String username;
    private final String password;

    public User(String username, String password) {
        this.username = username;
        this.password = password;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof User) {
            User user = (User) obj;
            return id.equals(user.getId()) &&
                    username.equals(user.getUsername()) &&
                    password.equals(user.getPassword());
        }
        return false;
    }

    public int hashCode() {
        return id.hashCode() + username.hashCode() * 31 + password.hashCode() * 31 * 31;
    }

    public String getId() {
        return id;
    }

    public String getUsername() {
        return username;
    }

    public String getPassword() {
        return password;
    }
}

打包机:

class UserWrapper {
    private final User user;

    public UserWrapper(User user) {
        this.user = user;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof UserWrapper) {
            UserWrapper userWrapper = (UserWrapper) obj;
            return user.getUsername().equals(userWrapper.getUser().getUsername()) &&
                    user.getPassword().equals(userWrapper.getUser().getPassword());
        }
        return false;
    }

    public int hashCode() {
        return user.getUsername().hashCode() + user.getPassword().hashCode() * 31;
    }

    public User getUser() {
        return user;
    }
}

查找

class DuplicateUserFinder {

    public List<UserWrapper> findDuplicates(List<UserWrapper> allUsers) {
        final List<UserWrapper> duplicateList = new ArrayList<UserWrapper>();
        final Set<UserWrapper> duplicateSet = new HashSet<UserWrapper>();

        for (UserWrapper wrapper : allUsers) {
            if (duplicateSet.contains(wrapper)) {
                duplicateList.add(wrapper);
            } else {
                duplicateSet.add(wrapper);
            }
        }

        return duplicateList;
    }

}

单元测试:

public class DuplicateUserFinderTest {

    private final DuplicateUserFinder finder = new DuplicateUserFinder();

    @Test
    public void shouldReturnEmptyIfNoDuplicates() {
        User user1 = new User("user1", "pass1");
        User user2 = new User("user2", "pass2");
        UserWrapper userWrapper1 = new UserWrapper(user1);
        UserWrapper userWrapper2 = new UserWrapper(user2);

        Assert.assertTrue(finder.findDuplicates(Arrays.asList(userWrapper1, userWrapper2)).isEmpty());
    }

    @Test
    public void shouldReturnDuplicates() {
        User user1 = new User("user", "pass");
        User user2 = new User("user", "pass");
        UserWrapper userWrapper1 = new UserWrapper(user1);
        UserWrapper userWrapper2 = new UserWrapper(user2);

        Assert.assertTrue(finder.findDuplicates(Arrays.asList(userWrapper1, userWrapper2)).contains(userWrapper2));
        Assert.assertThat(finder.findDuplicates(Arrays.asList(userWrapper1, userWrapper2)).size(), CoreMatchers.equalTo(1));
    }

}