1

我有一个很好的问题 -创建一个电话簿- 包含联系人列表。就像电话簿一样,

  1. 联系人将始终排序。(按名称)
  2. 可以星号标记某些联系人,所以他们必须高于所有其他人。(*联系人按联系人创建时间排序)

    class PhoneBook{
    //require an always sorted d.s
    TreeSet<Contact> contacts = new TreeSet<Contact>();
    
    @Override
    public String toString() {
        return "PhoneBook [contacts=" + contacts + "]";
    }
    
    public boolean addContact(Contact contact){
        //validate before adding the contact.
        return contacts.add(contact);
    }
    

    }

    class Contact implements Comparable<Contact>{
    String name;
    int phoneNo;
    Date timeAdded;
    boolean starContact;
    
    
    
    public Contact(String name, int phoneNo, Date timeAdded, boolean starContact) {
        super();
        this.name = name;
        this.phoneNo = phoneNo;
        this.timeAdded = timeAdded;
        this.starContact = starContact;
    }
    
    
    
    @Override
    public int compareTo(Contact otherContact) {
        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);
        }
    }
    
    
    
    
    
    
    @Override
    public String toString() {
        return "\nContact [name=" + name + ", timeAdded=" + timeAdded
                + ", starContact=" + starContact + "]";
    }
    
    
    }
    

测试代码

    public class MobilePhoneBookDemo {

/**
 * @param args
 */
public static void main(String[] args) {

    PhoneBook phoneBook = new PhoneBook();

    Contact frnd1 = new Contact("Z",56,new Date(),false);
    phoneBook.addContact(frnd1);
    Contact frnd2 = new Contact("A",3,new Date(),false);
    phoneBook.addContact(frnd2);
    Contact frnd3 = new Contact("C",30,new Date(),false);
    phoneBook.addContact(frnd3);
    try {
        TimeUnit.SECONDS.sleep(1);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    Contact ta = new Contact("Ta", 5, new Date(), true);
    phoneBook.addContact(ta);
    Contact ma = new Contact("Ma", 31, new Date(), true);
    phoneBook.addContact(ma);
    Contact baba = new Contact("Baba", 300, new Date(), true);
    phoneBook.addContact(baba);

    //change the priority later for one of my friends.
    System.out.println(phoneBook);
    frnd1.starContact = true;
    System.out.println(phoneBook.contacts.contains(frnd1));

    if(phoneBook.contacts.remove(frnd1)){
        System.out.println("removed");
        phoneBook.contacts.add(frnd1);
    }

    System.out.println(phoneBook);
}

}

面临的问题:

  1. 包含不再找到条目,有什么问题?我确实尝试在 Contact 上放置一个等号和一个哈希码,显然,如果存在 Comparator/Comparable,则仅调用 compare*。
  2. 在这里使用 TreeSet 是否公平,还是应该使用任何其他数据结构?例如。HashSet然后转换成TreeSet?
  3. contains() 甚至不比较地图中的所有条目,它只是与 C、Ma 和 Ta 条目进行比较。那是为什么?

题目按顺序排列。我感谢所有的答案,但这确实是一个完整的测试用例,所以请在提供答案之前尝试运行一次电话簿。非常感谢。

4

3 回答 3

4

这一行:

return this.timeAdded.before(otherContact.timeAdded)?-1:1;

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

于 2013-01-17T09:36:20.030 回答
1

你让我在

联系人将始终排序。(按名称)

如果顺序很重要,请使用 TreeSet。元素存储在各种二叉搜索树中,这意味着它们是默认排序的。

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


编辑 - 尝试以这种方式编写您的条件,更易读且更健壮。条件的顺序是比较的优先顺序。

if(a != b){
    return a<b;
}

if(c != d) {
    return c<d;
}

//and so on.

return 0;
于 2013-01-17T09:32:59.170 回答
0

解决方案很简单,先删除,然后更改值并重新添加。我先评论修改,我也加入了修改后的 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);
    }
}
于 2013-01-18T08:07:41.877 回答