Java 电话簿编程-TreeSet或HashSet

Java 电话簿编程-TreeSet或HashSet,java,equals,treeset,Java,Equals,Treeset,我有一个很好的问题-创建一个包含联系人列表的电话簿。 正如电话簿所说 联系人应始终按姓名排序 星号能确定吗 联系人,因此他们必须高于所有其他联系人 按联系人创建时间排序) } 面临的问题: 容器再也找不到条目了,有什么问题吗? 我试着在Contact上加上一个equals和一个hashcode,显然,如果存在一个Comparator/Comparable,那么compare*只会被调用 在这里使用树集公平吗,还是应该使用任何其他数据结构? 例如,HashSet,然后转换为TreeSet cont

我有一个很好的问题-创建一个包含联系人列表的电话簿。 正如电话簿所说

  • 联系人应始终按姓名排序
  • 星号能确定吗 联系人,因此他们必须高于所有其他联系人 按联系人创建时间排序)

    }

    面临的问题:

  • 容器再也找不到条目了,有什么问题吗? 我试着在Contact上加上一个equals和一个hashcode,显然,如果存在一个Comparator/Comparable,那么compare*只会被调用
  • 在这里使用树集公平吗,还是应该使用任何其他数据结构? 例如,HashSet,然后转换为TreeSet
  • contains()甚至不会比较映射中的所有条目,它只是与C、Ma和Ta条目进行比较。为什么会这样
  • 问题按顺序排列。 我感谢所有的答案,但这确实是一个完整的测试用例,所以请在提供答案之前尝试运行电话簿一次。非常感谢。

    你让我在

    联系人应始终按姓名排序

    如果订单很重要,请使用TreeSet。元素存储在各种二进制搜索树中,这意味着默认情况下对它们进行排序

    另一方面,HashSet不保证任何顺序、排序甚至插入顺序


    编辑-尝试以这种方式编写您的条件,使其更具可读性和健壮性。条件的顺序是比较的优先顺序

    if(a != b){
        return a<b;
    }
    
    if(c != d) {
        return c<d;
    }
    
    //and so on.
    
    return 0;
    
    如果(a!=b){
    返回一个你让我在

    联系人应始终按姓名排序

    如果顺序很重要,请使用TreeSet。元素存储在各种二进制搜索树中,这意味着默认情况下对它们进行排序

    另一方面,HashSet不保证任何顺序、排序甚至插入顺序


    编辑-尝试以这种方式编写条件,更具可读性和健壮性。条件的顺序是比较的优先级顺序

    if(a != b){
        return a<b;
    }
    
    if(c != d) {
        return c<d;
    }
    
    //and so on.
    
    return 0;
    
    如果(a!=b){
    返回一个此行:

    返回此.timeAdded.before(otherContact.timeAdded)?-1:1;

    如果将联系人与其自身进行比较,则将永远不会返回0。因此,集合将无法找到具有
    contains()
    此行的对象:

    返回此.timeAdded.before(otherContact.timeAdded)?-1:1;


    如果将联系人与自身进行比较,则将永远不会返回0。因此,集合将无法找到包含有
    contains()

    的对象解决方案很简单,首先删除,然后更改值,然后重新添加。 我首先对修改进行评论,我还加入了修改后的compareTo(),因为它有很多混乱之处

    //frnd1.starContact = true;
        System.out.println("Entry present>"+phoneBook.contacts.contains(frnd1));
    
        if(phoneBook.contacts.remove(frnd1)){
            System.out.println("removed");
            frnd1.starContact = true;
            phoneBook.contacts.add(frnd1);
        }
    
    
    @Override
    public int compareTo(Contact otherContact) {
        if(otherContact.phoneNo == this.phoneNo){
            return 0;
        }
        if(this.starContact && otherContact.starContact){
            return this.timeAdded.before(otherContact.timeAdded)?-1:1; //impossible to add 2 contacts at the same time
        }else if(this.starContact){
            return -1;
        }else if(otherContact.starContact){
            return 1;
        }else{
            //simple Contacts
            return this.name.compareTo(otherContact.name);
        }
    }
    

    解决方案很简单,首先删除,然后更改值并再次添加。 我首先对修改进行评论,我还加入了修改后的compareTo(),因为它有很多混乱之处

    //frnd1.starContact = true;
        System.out.println("Entry present>"+phoneBook.contacts.contains(frnd1));
    
        if(phoneBook.contacts.remove(frnd1)){
            System.out.println("removed");
            frnd1.starContact = true;
            phoneBook.contacts.add(frnd1);
        }
    
    
    @Override
    public int compareTo(Contact otherContact) {
        if(otherContact.phoneNo == this.phoneNo){
            return 0;
        }
        if(this.starContact && otherContact.starContact){
            return this.timeAdded.before(otherContact.timeAdded)?-1:1; //impossible to add 2 contacts at the same time
        }else if(this.starContact){
            return -1;
        }else if(otherContact.starContact){
            return 1;
        }else{
            //simple Contacts
            return this.name.compareTo(otherContact.name);
        }
    }
    

    如果必须始终对联系人进行排序,请使用TreesetTreeMap或TreeMapIt was来响应之前的注释,其中提到使用TreeMap,但现在它已更改为TreeSet。如果必须始终对联系人进行排序,请使用TreesetTreeMap或TreeMapIt was来响应之前的注释,其中提到使用TreeMap,它现在改为树集。真的吗?那么compareTo()将与自身进行比较?我几乎没有测试就重复了这个答案,因为它看起来很好,但实际上不起作用。contain()从未调用compareTo()关于它自己。噢,downvoter,想解释一下吗?我认为应该这样要求所有的downvoter至少留下评论,这样downvoter才有责任。查看
    TreeMap.getKey()
    (其中
    TreeSet.contains()
    的代码)它使用比较器来查找您要查找的对象。因此,如果集合包含
    frnd1
    ,则调用
    set.contains(frnd1)
    将返回为“compareTo()”提供0的对象。在这种情况下,该对象将不包含任何条目,因此返回
    null
    @anirbanchowdhury。如果您搞错了,它将调用compareTo()将搜索键与输入键进行比较时,对树进行二元搜索,直到它返回零为止。@EJP,是的,我的错误是,compareTo()可能会将它与自身进行比较,但如果您怀疑我,则不一定只进行一次调试以检查它。但是,这并不能解决问题。真的吗?那么compareTo()我几乎没有测试就重复了这个答案,因为它看起来很好,但实际上不起作用。contain()从未调用compareTo()关于它自己。噢,downvoter,想解释一下吗?我认为应该这样要求所有的downvoter至少留下评论,这样downvoter才有责任。查看
    TreeMap.getKey()
    (其中
    TreeSet.contains()
    的代码)它使用比较器来查找您要查找的对象。因此,如果集合包含
    frnd1
    ,则调用
    set.contains(frnd1)
    将返回为“compareTo()”提供0的对象。在这种情况下,该对象将不包含任何条目,因此返回
    null
    @anirbanchowdhury。如果您搞错了,它将调用compareTo()将搜索键与输入键进行比较时,对树进行二元搜索,直到返回零为止。@EJP,是的,我的错误,compareTo()可能会将其与自身进行比较,但并非总是如此,如果您怀疑我,请只调试一次以检查它。然而,这并不能解决问题。@anirbanchowdhury您能否指出一个引用,该引用说
    等于
    将不起作用?“如果存在一个比较器/可比较项,则只会调用compare*。”请检查contains()在树集上以及它指向的位置。将导致树映射上的getEntry()。在这种情况下,Anras Kerekes指出的问题非常有效,但可能不是全部。@anirbanchowdhury“contains()甚至不会对映射中的所有条目进行比较,”您如何推断。@anirbanchowdhury实际上是问题所暗示的
    
    //frnd1.starContact = true;
        System.out.println("Entry present>"+phoneBook.contacts.contains(frnd1));
    
        if(phoneBook.contacts.remove(frnd1)){
            System.out.println("removed");
            frnd1.starContact = true;
            phoneBook.contacts.add(frnd1);
        }
    
    
    @Override
    public int compareTo(Contact otherContact) {
        if(otherContact.phoneNo == this.phoneNo){
            return 0;
        }
        if(this.starContact && otherContact.starContact){
            return this.timeAdded.before(otherContact.timeAdded)?-1:1; //impossible to add 2 contacts at the same time
        }else if(this.starContact){
            return -1;
        }else if(otherContact.starContact){
            return 1;
        }else{
            //simple Contacts
            return this.name.compareTo(otherContact.name);
        }
    }