首页 > 解决方案 > 使用 Comparator 会破坏对象的“唯一性”?

问题描述

给定 User 类,通过其用户名使每个用户都独一无二,并将流行度作为衡量用户流行度的计数器,有一种方法可以使用 TreeSet 来按流行度排列它们,并仍然保留由其 id 推断的对象的唯一性。

我尝试创建一个标准比较器,它首先采用优先级并减去它们,但注意到当两个用户具有相同的受欢迎程度时,只有一个用户被添加到 TreeSet 而另一个被忽略。

意识到这一点后,我尝试了下面代码中的另一个比较器,但它仍然不起作用。

任何建议/文章将不胜感激。

public class User{

    private int popularity;
    private String username;

 public User(String username) {
        this.username = username;
        this.popularity = 0;
      
    }

 public void incrementPopularity() {
        this.popularity++;
    }

    public int getPopularity() {
        return this.popularity;
    }


    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        User user = (User) o;
        return Objects.equals(username, user.username);
    }

    @Override
    public int hashCode() {
        return Objects.hash(username);
    }
   public static void main(String[] args) {

         // First comparator
         Set<User> users = new TreeSet<>(new Comparator<User>() {
           @Override
           public int compare(User o1, User o2) {
                 return o1.getPopularity() - o2.getPopularity();
           }
            );

        // Second comparator

       Set<User> users2 = new TreeSet<>(new Comparator<User>() {
           @Override
           public int compare(User o1, User o2) {
                 if(!o1.equals(o2) && o1.getPopularity() == o2.getPopularity() ) {
                      return -1;
                 }

                 return o1.getPopularity() - o2.getPopularity();
           }
            );
         
   }

}

标签: java

解决方案


你必须以某种方式打破关系;文档TreeSet明确指出,比较器认为相等的两个项目被视为重复项。

由于您有另一个可能是唯一的属性,您可以使用它来打破关系:

new TreeSet<>(Comparator.comparingInt(User::getPopularity).thenComparing(User::getUsername))

推荐阅读